javascript中的this词法
来源:互联网 发布:网络整合营销 编辑:程序博客网 时间:2024/06/06 12:36
this的绑定规则
this是在运行时进行绑定的,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。当一个函数被调用时,会创建一个活动记录(执行上下文),这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录其中的一个属性,会在函数执行的过程中用到。
绑定规则
1. 默认绑定
最常用的函数调用类型:独立函数调用。
function foo(){ console.log(this.a);}var a=2;foo();
this.a被解析成了全局变量a,因为函数调用应用了this的默认绑定,因此this指向全局变量。在这里,foo()直接使用了不带任何修饰符的函数引用进行调用,因此看出foo()只能使用默认绑定,无法应用其他规则。
如果使用严格模式,那么全局对象无法使用默认绑定,this会被绑定到undefined。严格模式下与foo()的调用位置无关。
2. 隐式绑定
考虑规则:调用位置是否有上下文,或者说是被某个对象包含。
function foo(){ console.log(this.a);}var obj={ a:2, foo:foo};obj.foo();
当foo()被调用时,它的落脚点指向了obj对象。当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象,因为调用foo时this绑定到obj,因此this.a和obj.a是一样的。
对象属性引用链中只有最顶层会影响调用位置。
function foo(){ console.log(this.a);}var obj2={ a:42; foo:foo};var obj1={ a:2, obj2:obj2};obj1.obj2.foo();//42
隐式丢失:一个常见的this绑定问题就是被隐式绑定的函数会丢失绑定对象,也就是说会应用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式。
function foo(){ console.log(this.a);}var obj={ a:2, foo:foo};var bar=obj.foo;//函数别名var a="oops,global";bar();
虽然bar是obj.foo的一个引用,但是,它引用了foo函数本身,因此此时的bar实际是一个不带任何修饰的函数调用,因此应用了默认绑定。
function foo(){ console.log(this.a);}function doFoo(fn){ fn();}var obj={ a:2, foo:foo};var a="oops,global";doFoo(obj.foo);//oops,global
参数传递实际就是一种隐式赋值,因此我们传入函数时也会被隐式赋值。
隐式绑定时,我们必须在一个对象内部包含一个指向函数的属性,并通过这个属性间接引用函数,从而把this绑定到这个对象上。
window.id='window';document.getElementById('div').onclick=function(){ alert(this.id);//div1 var callback=function(){ alert(this.id);//window }}
document.getElementById('div1').onclick=function(){ var that=this; var callback=function(){ alert(that.id);//div1 } callback();}
3. 显示绑定
显示绑定可以解决丢失绑定的问题
1、硬绑定
function foo(){ console.log(this.a);}var obj={ a:2};var bar=function(){ foo.call(obj);};bar();//2setTimeout(bar,100);//2//硬绑定的bar不能再修改它的thisbar.call(window);//2
硬绑定的应用场景就是创建一个包裹函数,传入所有的参数并返回接收到的所有值。
2、API调用的“上下文”
function foo(el){ console.log(el,this.id);}var obj={ id:"awesome"};[1,2,3].forEach(foo,obj);
4. new绑定
使用new来调用函数,会自动执行以下操作
1、创建一个新对象
2、这个新对象会被执行原型连接
3、这个新对象会被绑定到函数调用的this
4、如果函数没有返回其他对象,那么new表达式的函数调用会自动返回这个新对象。
判断this
1、函数是否在new中调用,如果是的话this绑定的是新创建的对象
2、函数是否通过call、apply或者硬绑定调用,如果是的话,this绑定的是指定的对象
3、函数是否在某个上下文对象中调用(隐式绑定),如果是的话,this绑定的是那个上下文对象
4、如果都不是的话,使用默认绑定,严格模式下,绑定到undefined,否则绑定到全局对象。
this的四种使用场景
this要在执行时才能确认值,定义时无法确认。
var a={ name:'A', fn:function(){ console.log(this.name) }}a.fn() //this===aa.fn.call({name:'B'})//this==={name:'B'}var fn1=a.fnfn1()//this===window
1、作为构造函数执行
function Foo(name){ this.name=name}var f=new Foo('zhangsan')
2、作为对象属性执行
var obj={ name:'A', printName:function(){ console.log(this.name) }}obj.printName()
3、作为普通函数执行
function fn(){ console.log(this)}fn()
4、call apply bind
function fn1(name){ alert(name); console.log(this)}fn1.call({x:100},'zhangsan')var fn2=function(name,age){ alert(name); console.log(this);}.bind({y:200})fn2('zhangsan',20)
- javascript中的this词法
- JavaScript的this词法
- JavaScript的this词法(二)
- JavaScript 中的词法作用域
- ES2015 中的箭头函数和词法 this
- this词法
- 【javascript】javascript中的this
- javascript中的作用域(词法and动态)
- JavaScript中的this指针
- javascript 中的"this"
- javascript中的this!
- Javascript中的this讲解
- Javascript中的this关键字
- javascript中的this
- JavaScript中的this关键字
- JavaScript中的this详解
- JavaScript中的this指针
- javascript中的this
- php链接mysql及mysqli深入透析
- How Tomcat works之(一个简单的web服务器)
- kafka 容器报内存不足异常(failed; error='Cannot allocate memory' (errno=12))
- 离线应用和本地存储
- 容器
- javascript中的this词法
- spring boot 下mybatis的mapper Could not autowire问题
- Mysql常用命令行集
- vue2.0 组件通信
- C语言指针变量作为函数参数
- 搭建开发环境
- PercentLayout中使用layout_aspectRatio属性报错
- Python多线程(2)——线程同步机制
- HTML基础学习-1