This in JavaScript
2016-07-17 22:30
543 查看
声明 本文仅为读书笔记并致力于理解Js中的this关键字。如有雷同,纯属巧合。原因有二,其一:有幸看了同一本书,其二:this这玩意已被说烂了~
1. 为什么要用this?
this提供了优雅的方式隐式传递对象的引用
上实例:
当不使用this时
两种对比,可以看出当不使用this时,需手动显式传递一个上下文对象。而使用了this可以使得代码很精炼。而且传递上下文的方式会使得代码越来越混乱。
2. 对this的误解
1)指向自身(书中代码)
为什么是0,而不是4?原因在于,此时调用foo函数的是window,this的指向是window。
解决办法有两种:
其一,用foo代替this。也就是foo.count++。
其二,强制this指向foo,通过call,或者apply。也就是在if里面改为foo.call(foo,i)。
2)指向函数的作用域
原因在于:调用foo的对象为window
3. 绑定规则
1)默认绑定
若函数是直接使用不带任何修饰的函数引用的,它便是应用了默认绑定。this指向window,上面的实例可以佐证。
p.s 当使用严格模式时,则不能将全局对象用于默认绑定
2)隐式绑定
本例就使用了默认绑定,this绑定在obj上。另外,对象属性引用链只有上一层或者说最后一层在调用位置中起作用。也即,obj1.obj2.foo(),this绑定在obj2中。
但是,隐式绑定经常会有一个问题产生–隐式丢失
this的指向不再是obj,而变成了window。丢失了this的指向。同理还有当obj.foo作为参数传递时丢失,原因在于参数传递相当于两个步骤,一赋值,二参数传递。
3)显示传递
通过call、apply的方式,将this绑定在对象上。具体call、apply的使用方法见本人博客Call and Apply in JavaScript
4)new绑定
使用new调用时,会构造一个对象并将this指向进行绑定。如本例的foo上。
4. 优先级
new绑定>显示绑定>隐式绑定>默认绑定
本人较懒,部分代码原封不动摘抄自原著。还请见谅
1. 为什么要用this?
this提供了优雅的方式隐式传递对象的引用
上实例:
function sayEng(){ console.log(this.name+":sayEng"); } function sayChi(){ console.log(this.name+":sayChi"); } function stu(){ name = "stu"; } function tea(){ name = "tea"; } sayEng.call(stu);//stu:sayEng sayEng.call(tea);//tea:sayEng sayChi.call(stu);//stu:sayChi
当不使用this时
function sayEng(ctx){ console.log(ctx.name+"sayEng"); } function sayChi(ctx){ console.log(ctx.name+"sayChi"); } function stu(){ name = "stu"; } function tea(){ name = "tea"; } sayEng(stu);//stu:sayEng sayEng(tea);//tea:sayEng sayChi(stu);//stu:sayChi sayChi(tea);//stea:sayChi
两种对比,可以看出当不使用this时,需手动显式传递一个上下文对象。而使用了this可以使得代码很精炼。而且传递上下文的方式会使得代码越来越混乱。
2. 对this的误解
1)指向自身(书中代码)
function foo(num) { console.log( "foo: " + num ); // count用于记录foo的被调用次数 this.count++; } foo.count = 0; var i; for (i=0; i<10; i++) { if (i > 5) { foo( i ); } } console.log( foo.count ); // 0 -- ??
为什么是0,而不是4?原因在于,此时调用foo函数的是window,this的指向是window。
解决办法有两种:
其一,用foo代替this。也就是foo.count++。
其二,强制this指向foo,通过call,或者apply。也就是在if里面改为foo.call(foo,i)。
2)指向函数的作用域
function foo() { var a = 2; this.bar(); } function bar() { console.log( this.a ); } foo(); //ReferenceError:a is not defined
原因在于:调用foo的对象为window
3. 绑定规则
1)默认绑定
若函数是直接使用不带任何修饰的函数引用的,它便是应用了默认绑定。this指向window,上面的实例可以佐证。
p.s 当使用严格模式时,则不能将全局对象用于默认绑定
2)隐式绑定
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
本例就使用了默认绑定,this绑定在obj上。另外,对象属性引用链只有上一层或者说最后一层在调用位置中起作用。也即,obj1.obj2.foo(),this绑定在obj2中。
但是,隐式绑定经常会有一个问题产生–隐式丢失
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // 函数别名 var a = "oops,global"; bar(); // "oops,globa"
this的指向不再是obj,而变成了window。丢失了this的指向。同理还有当obj.foo作为参数传递时丢失,原因在于参数传递相当于两个步骤,一赋值,二参数传递。
3)显示传递
通过call、apply的方式,将this绑定在对象上。具体call、apply的使用方法见本人博客Call and Apply in JavaScript
4)new绑定
function foo(a) { this.a = a; } var bar = new foo( 2 ); console.log( bar.a );// 2
使用new调用时,会构造一个对象并将this指向进行绑定。如本例的foo上。
4. 优先级
new绑定>显示绑定>隐式绑定>默认绑定
本人较懒,部分代码原封不动摘抄自原著。还请见谅
相关文章推荐
- jsDOM编程-拖拽层
- jstl标签和EL表达式知识点归纳
- This in JavaScript
- 从零开始学_JavaScript_系列(25)——dojo(10)摧毁一个widget
- 从零开始学_JavaScript_系列(24)——查看对象属性,合并数组
- Servlet技术
- JavaScript闭包的理解
- 将DataSet转换成json
- JavaScript线程
- jsDOM编程-小球在盒子里来回撞击
- JS--比想象中简单
- JS数组去重和排序方法总结
- 程 序制作步骤,三级联动,委托事件和Repeater灵活运用以及JS知识补充
- 深入分析javascript中的错误处理机制
- codecademy--javascript
- jsp简单的计算器如何在本页显示数据
- js知识
- JS 实现选项卡切换
- C#——JSON转换为对象
- js中==与===的区别