【笔记】探索js 的this 对象 (第二部分)
2017-03-21 23:22
477 查看
了解this对象之后我们明白了this对象就是指向调用函数的作用域
那么接下来我们便要清除函数究竟在哪个作用域调用
找到调用的作用域首先要了解一下几点:
1、调用栈:调用栈就是一系列的函数,表明当前函数是由哪些上层函数调用的包括它自身,我们关心的调用位置就在当前正在执行的函数的前一个调用中。
这段代码的意思是,函数再哪个区域被调用那个区域就是它的执行环境
找到了调用位置就要理解一下函数对this对象的绑定了
一般分为一下4种:
1、默认绑定
指函数在调用的过程中没有任何干涉调用位置的代码浏览器引擎根据调用栈默认绑定
默认绑定,函数的this对象会指向了window对象而在严格模式下函数访问this会显示undefined
例子:
2、隐式绑定
函数没有调用任何方法绑定而是在调用时根据对象上下文绑定了this的作用域
看一下下面的例子
//通过obj调用函数foo,所以foo的this对象绑定在了obj上
//严格来说函数foo不属于obj对象但由于函数是通过obj引用并调用的所以this指向了obj
另外对象调用链中只有最靠近被调用函数那层会影响函数的调用位置
即:函数在某一个对象里面通过那个对象调用函数this永远指向那个对象
例如:
这里的意思是:obj1调用obj2然后obj2再调用bar这个函数引用
从逻辑上说bar这个函数调用怎么也是属于obj2吧
另外dom的事件绑定回调函数也会把this绑定在执行事件的dom元素对象上
小分支:
2.1、隐式丢失
隐式绑定的函数会丢失原来的this所引用的对象
丢失后的this会引用到全局对象或undefined
例1:
把函数的引用赋值给全局变量会丢失原来的this绑定
这里的函数foo的引用虽然是obj里面的一个属性值,但是后面却把函数的引用赋值给了一个全局变量并且在全局环境执行,所以foo的this对象指向了window对象
其实这里真正的误区是我们一直以为在对象字面量中属性值为函数就是函数this绑定的区域,其实不然
回顾一下第一部分的话,函数在哪里调用,那里才是它this对象绑定的环境
所以这次函数foo的引用在(保存在了bar中)在全局调用所以this指向了全局
例2:
把函数的引用当作参数传进另外一个函数被执行会造成隐式丢失
这里dofoo的输出结果是"globalwindow"
同时,回调函数也会造成隐式丢失
3、显式绑定
通过语言内置的方法将函数硬性绑定在了某一对象上执行
例如通过call(),apply(),bind()方法
此时函数的this对象绑定在了bind()和apply()方法的参数上
例如:
3.1、硬绑定
通过提供的方法,将函数绑定在某一对象上执行
例:
apply和call方法能够执行这种硬性绑定
除了这两个es5语法还定义了新方法bind()
例:
new绑定:
js的new关键字不等同于其他面向对象语言里的new
js的new关键字仅仅是调用它的目标函数而已
1、调用new关键字会创建一个新对象
2、新对象会与函数的原型连接
3、将函数的this绑定到了新对象上
4、如果函数没有返回指定的新对象那么就会返回一个默认的对象
例:
上例中我们通过new将foo函数实例化并将this指针指向了bar
于是bar便拥有了函数中的a属性
以上四种绑定的优先级
默认绑定最低
隐式绑定低于显示绑定
隐式绑定又低于new绑定
而new与显示绑定其实两个本身的并没有什么影响很难说明优先级
如下例:
小结:
这部分内容主要讲述了函数的this绑定位置以及各种的绑定方式,有如下结论
1、当函数被new实例化时,this对象指向新返回的对象
2、当函数调用了call(),apply()或者bind(),this绑定在指定的对象
3、函数在某个对象字面量里面调用,this绑定在了这个对象字面量里面
4、以上都没有被操作,在非严格模式下函数的this指向了window对象,严格模式下为undefined
那么接下来我们便要清除函数究竟在哪个作用域调用
找到调用的作用域首先要了解一下几点:
1、调用栈:调用栈就是一系列的函数,表明当前函数是由哪些上层函数调用的包括它自身,我们关心的调用位置就在当前正在执行的函数的前一个调用中。
functionbaz(){ //调用栈:baz函数的内部 console.log("baz函数内部"); bar(); } functionbar(){ //调用栈分别是baz->bar //调用位置为baz因此bar的this指针指向baz console.log("bar函数内部"); foo(); } functionfoo(){ //调用栈分别为baz->bar->foo //调用位置是bar内部因此foo的this指针指向了bar console.log("foo函数的内部"); } baz()//baz的调用位置是全局作用域
这段代码的意思是,函数再哪个区域被调用那个区域就是它的执行环境
找到了调用位置就要理解一下函数对this对象的绑定了
一般分为一下4种:
1、默认绑定
指函数在调用的过程中没有任何干涉调用位置的代码浏览器引擎根据调用栈默认绑定
默认绑定,函数的this对象会指向了window对象而在严格模式下函数访问this会显示undefined
例子:
functionfoo(){ console.log(this.a); } vara="i'mwindow"; foo();//输出2因为全局变量也是window对象的属性
2、隐式绑定
函数没有调用任何方法绑定而是在调用时根据对象上下文绑定了this的作用域
看一下下面的例子
functionfoo(){ console.log(this.a); } varobj={ a:"i'mobj", foo:foo//对象obj中包含着foo的引用 } obj.foo();
//通过obj调用函数foo,所以foo的this对象绑定在了obj上
//严格来说函数foo不属于obj对象但由于函数是通过obj引用并调用的所以this指向了obj
另外对象调用链中只有最靠近被调用函数那层会影响函数的调用位置
即:函数在某一个对象里面通过那个对象调用函数this永远指向那个对象
例如:
functionbar(){
console.log(this.a);
}
varobj2={
a:"i'mobj2",
bar:bar,
}
varobj1={
a:"i'mobj1",
obj2:obj2,
bar:bar
}
obj1.obj2.bar();
这里的意思是:obj1调用obj2然后obj2再调用bar这个函数引用
从逻辑上说bar这个函数调用怎么也是属于obj2吧
另外dom的事件绑定回调函数也会把this绑定在执行事件的dom元素对象上
小分支:
2.1、隐式丢失
隐式绑定的函数会丢失原来的this所引用的对象
丢失后的this会引用到全局对象或undefined
例1:
把函数的引用赋值给全局变量会丢失原来的this绑定
functionfoo(){
console.log(this.a);
}
varobj={
a:"i'mobj",
foo:foo
}
varbar=obj.foo;
//把objfoo属性里面对foo函数的引用赋值给了全局变量bar
vara="globalwindow";
bar();
这里的函数foo的引用虽然是obj里面的一个属性值,但是后面却把函数的引用赋值给了一个全局变量并且在全局环境执行,所以foo的this对象指向了window对象
其实这里真正的误区是我们一直以为在对象字面量中属性值为函数就是函数this绑定的区域,其实不然
回顾一下第一部分的话,函数在哪里调用,那里才是它this对象绑定的环境
所以这次函数foo的引用在(保存在了bar中)在全局调用所以this指向了全局
例2:
把函数的引用当作参数传进另外一个函数被执行会造成隐式丢失
functionfoo(){
console.log(this.a);
}
functiondofoo(fn){
fn();
}
varobj={
a:"i'mobj",
foo:foo
}
vara="globalwindow";
dofoo(obj.foo);
这里dofoo的输出结果是"globalwindow"
同时,回调函数也会造成隐式丢失
setTimeout(obj.foo,1000);//"globalwindow"
3、显式绑定
通过语言内置的方法将函数硬性绑定在了某一对象上执行
例如通过call(),apply(),bind()方法
此时函数的this对象绑定在了bind()和apply()方法的参数上
例如:
functionfoo(){
console.log(this.a);
}
varobj={
a:"i'mobj",
}
//把foo函数绑定在obj上执行
foo.call(obj);//i'mobj
3.1、硬绑定
通过提供的方法,将函数绑定在某一对象上执行
例:
functionfoo(){
console.log(this.a);
}
varobj={
a:"i'mobj",
}
setTimeout(functiontimer(){
//回调函数通常会丢失this
//在回调函数中使用硬性绑定就不会出现这个现状了
foo.call(obj);//把foo硬性绑定在obj上执行
},1000);//i'mobj
obj.call(window);//硬性绑定之后无法再绑定其他对象
apply和call方法能够执行这种硬性绑定
除了这两个es5语法还定义了新方法bind()
例:
functionfoo(num){
returnthis.a+num;
}
varobj={
a:2
}
varbar=foo.bind(obj);//把foo函数的引用绑定在了obj上
varresult=bar(3);
console.log(result);//5
new绑定:
js的new关键字不等同于其他面向对象语言里的new
js的new关键字仅仅是调用它的目标函数而已
1、调用new关键字会创建一个新对象
2、新对象会与函数的原型连接
3、将函数的this绑定到了新对象上
4、如果函数没有返回指定的新对象那么就会返回一个默认的对象
例:
functionfoo(){
this.a="whocantakemego";
}
varbar=newfoo();
console.log(bar.a);
上例中我们通过new将foo函数实例化并将this指针指向了bar
于是bar便拥有了函数中的a属性
以上四种绑定的优先级
默认绑定最低
隐式绑定低于显示绑定
隐式绑定又低于new绑定
而new与显示绑定其实两个本身的并没有什么影响很难说明优先级
如下例:
functionfoo(arg1){
this.a=arg1;
}
varobj={};
varbar=foo.bind(obj);
//将foo函数的引用绑定在obj上
//然后将obj上对函数foo的引用传值给bar
bar(2);
console.log(obj.a);
//现在将引用这foo.bind(obj)的变量bar实例化
varbaz=newbar(5);
console.log(baz.a);//5
//此操作没有修改obj的属性a值,并且把新值添加到了新的对象上baz
小结:
这部分内容主要讲述了函数的this绑定位置以及各种的绑定方式,有如下结论
1、当函数被new实例化时,this对象指向新返回的对象
2、当函数调用了call(),apply()或者bind(),this绑定在指定的对象
3、函数在某个对象字面量里面调用,this绑定在了这个对象字面量里面
4、以上都没有被操作,在非严格模式下函数的this指向了window对象,严格模式下为undefined
相关文章推荐
- 【笔记】探索js 的this 对象 (第三部分)
- 【笔记】探索js 的this 对象 (第一部分)
- 2016.06.14廖雪峰JS__学习笔记(对象部分)__P5
- 你不知道的JavaScript 上卷 第二部分 this和对象原型
- 更新一个js中的this的四个指代对象,作为学习笔记
- 笔记 js中this对象详解
- 让您对js的 function, javascript内置对象,this概念及之间的关系不再迷惑
- js的 function, javascript内置对象,this概念及之间的关系不再迷惑。
- 数据库系统概论 学习笔记(三)第二部分
- js高级编号笔记[新]-访问文档对象
- js高级编号笔记[新]-9个核心对象
- 深度探索C++对象模型 Data语意学笔记
- VoIP学习笔记第二部分:语音编码
- js学习笔记(十二)Document对象
- 分布式、并行计算语言Erlang 学习笔记(第二部分)
- Windows Phone 7 开发探索笔记8——加载XAML文件中的对象
- 学习JavaScript 的必备 (一),让您对js的 function, javascript内置对象,this概念及之间的关系不再迷惑。(希望能置为推荐篇,为更多的js初学者关注)
- 学习JavaScript 的必备 (一),让您对js的 function, javascript内置对象,this概念及之间的关系不再迷惑。(希望能置为推荐篇,为更多的js初学者关注)
- 让您对js的 function, javascript内置对象,this概念及之间的关系不再迷惑
- 深度探索c++对象模型 学习笔记 chapter2-1 default constructor