““You know nothing Jon Snow”web
““你不知道的JavaScript学习笔记02”app
function foo() {
console.log(this.a) } var a = "fuck"; foo();//fuck 复制代码
var obj1 = {
a:1, foo:function() { console.log(this.a); } } var obj2 = { b:2, bar:function() { consolelog(this.b); } } obj1.foo();//1 obj2.bar();//2 复制代码
function foo() {
console.log(this.a); } var obj1 = { a:1, foo:foo } var obj2 = { a:2, obj1 } var obj3 = { a:3, obj2 } obj3.obj2.obj1.foo(); //1; 复制代码
var obj1 = {
a:1, foo:function() { console.log(this.a); } } var a = "shit"; var bar = obj1.foo; bar(); //shit 复制代码
在js中,函数属于Object的之类,在这块代码块中的RHS其实是传递函数的引用,而this是由调用宿主和执行上下文决定的,函数执行时执行的是默认绑定的规则编辑器
var obj1 = {
a:1 } function foo() { console.log(this.a); } var a = 2; foo.call(obj1); // 1 foo.apply(obj1); //1 var bar = foo.bind(obj1); bar(); //1 复制代码
new关键字函数
avaScript中的“构造函数”有别于其余语言,在JavaScript中,在函数调用前用new关键字进行声明,该函数就成了“构造函数”,函数自己并没有区别。 使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操做。1.建立(或者说构造)一个全新的对象。2.这个新对象会被执行[[Prototype]]链接。3.这个新对象会绑定到函数调用的this。4.若是函数没有返回其余对象,那么new表达式中的函数调用会自动返回这个新对象。学习
//eg
function myNew() { // 第一个参数是构造函数 var Constructor = [].shift.call(arguments); // 建立一个继承对象 var obj = Object.create(Constructor.prototype); // 执行构造函数,this执行obj var result = Constructor.apply(obj, arguments); // 构造函数返回是对象,优先使用返回的对象,不然是obj return result instanceof Object ? result : obj; // 执行构造函数,this执行obj var result = Constructor.apply(obj, arguments); // 构造函数返回是对象,优先使用返回的对象,不然是obj return result instanceof Object ? result : obj; } var a = 'fuck'; function foo(a) { this.a = a; this.saya = function() { console.log(this.a) } } var b = "shit"; var obj = myNew(foo,b); // new foo(b) obj.saya; //shit; 复制代码
使用new来调用foo(..)时,咱们会构造一个新对象并把它绑定到foo(..)调用中的this上。new是最后一种能够影响函数调用时this绑定行为的方法,咱们称之为new绑定。ui
“new绑定 > 显式绑定 >隐式绑定 >默认绑定this
能够按照下面的顺序来进行判断:url
1.函数是否在new中调用(new绑定)?spa
若是是的话this绑定的是新建立的对象。prototype
var obj = new foo(); //绑定obj
复制代码
2.函数是否经过call、apply(显式绑定)或者硬绑定调用?
若是是的话,this绑定的是指定的对象。
var bar = new foo.call(obj); //绑定obj
复制代码
3.函数是否在某个上下文对象中调用(隐式绑定)?
若是是的话,this绑定的是那个上下文对象。
var bar = obj.foo(); //绑定obj
复制代码
4.若是都不是的话,使用默认绑定。若是在严格模式下,就绑定到undefined,不然绑定到全局对象。
箭头函数并非使用function关键字定义的,而是使用被称为“胖箭头”的操做符=>定义的。箭头函数不使用this的四种标准规则,而是根据外层(函数或者全局)做用域来决定this。
function foo() {
return (a) => { console.log(this.a) } } var obj1 = { a:1 } var obj2 = { a:2 } var bar = foo.call(obj1); bar.call(obj2); //1,不是2 复制代码
foo内部的箭头函数会捕获调用foo时的this;箭头函数的this查询规则听从词法;外层函数绑定的this会间接传递给内部的箭头函数,箭头函数的绑定没法被修改。
function foo() {
var _this = this; setTimeout(function(){ console.log(_this.a) },100) } function bar() { setTimeout(()=>{ console.log(this.a) },100) } function baz() { setTimeout(function(){ console.log(this.a) },100) } var obj = { a: 1 } var a = 2; foo.call(obj); //1 bar.call(obj); //1 baz.call(obj); //2, 天惹,回调函数的this执行了默认绑定 复制代码
“参考文献: 《你不知道的JavaScript(上卷)》
本文使用 mdnice 排版