this,是指当前的本身,在非严格模式下this指向的是全局对象window,而在严格模式下会绑定到undefined。
1. this
this的5种绑定方式:
1.1 默认绑定
(非严格模式下this指向全局对象,严格模式下this会绑定到undefined)
例1:
let a = 10 const b = 20 function foo(){ console.log(this.a) console.log(this.b) } foo() console.log(window.a) console.log(window.b) // 结果 全是undefined // **************************************
四个全是undefined
例2:
var a = 1; function foo(){ var a = 2; console.log(this) console.log(this.a) // 1 } foo()
例3:
打印出了this 和 a了
var a = 1; function foo(){ var a = 2; function inner(){ console.log(this.a) // 1 } inner() } foo()
成功打印出外层的a
1.2 隐式绑定
(当函数引用有上下文对象时,如 obj.foo()的调用方式,foo内的this指向obj)
例1
function foo(){ console.log(this.a) } var obj = {a:1,foo} var a = 2 obj.foo() //1 // 等于如下代码 var obj = { a:1, foo:function(){ console.log(this.a) } } obj.foo()
this永远以调用为主
例2:
function foo(){ console.log(this.a) } var obj = {a:1,foo}; var a = 2 var foo2 = obj.foo; obj.foo(); //1 foo2(); // 2
调用foo2时,调用了a=2
例3:
function foo(){ console.log(this.a) } var obj = {a:1,foo}; var a = 2 var foo2 = obj.foo; var obj2 ={a:3,foo2:obj.foo} obj.foo(); //1 foo2(); // 2 obj2.foo2() //3
依次调用。先执行内部a=1
- obj.foo()中的this指向调用者 obj
- foo2() 发生了隐式丢失,调用者 是window 使得foo()中的this指向了window
- foo3() 发生了隐式丢失,调用者是obj2,使得 foo()中的this 指向了obj2
例4:
function foo(){ console.log(this.a) } function doFoo(fn){ console.log(this) fn() } var obj = {a:1,foo} var a = 2 var obj2 = {a:3,doFoo} obj2.doFoo(obj.foo)
在调用doFoo时又调用了obj的a=1
所以说,如果你一把一个函数当成参数传递到另一个函数的时候 也会发生隐性丢失的问题,且与包裹着他的函数的this指向无关,在严格模式下,会把函数的this绑定到window上,严格模式下绑定到undefined
1.3 显示绑定
(通过call()或者apply()方法直接指定this的绑定对象,如foo.call(obj)
使用.call()或者apply()的函数是会直接执行的
bind(()是创建一个新的函数,需要手动调用才会执行
.call()和.apply()用法基本类似,不过call搞收若干个参数,而apply接受的却是一个数组
function foo () { console.log(this.a) } var obj = { a: 1 } var a =2 foo()//2 foo.call(obj) //1 foo.apply(obj) // 1 foo.bind(obj) // foo () {console.log(this.a)}
例2:
var obj1 = { a:1 } var obj2 = { a:2, foo1:function(){ console.log(this.a) }, foo2:function(){ setTimeout(function(){ console.log(this) console.log(this.a) },0) } } var a = 3 window.setTimeout(function(){ console.log(this) console.log(this.a) //3 },0)
永远记住
this指向最后的那个对象
2. new绑定。
new的过程中到底发生了什么?
1.新生成了一个对象
2.链接到原型
3.绑定 this
4.返回新对象
接下来,我们假装手写一个new方法,看看 new究竟做了些什么。
2.1 箭头函数绑定
(this的指向由外层作用域决定的)
它里面的this是由外层作用域来决定的,且指向函数定义时的this而非执行时
ES6标准新增了一种新的函数: Arrow Function (箭头函数)
为什么叫Arrow Function?因为它的定义用的就是一个箭头。
X => x*x // 相当于 function (x){ return x * x; }
2.2 如何使用严格模式
直接卸载 script里面的代码 叫做严格模式的代码
“use strict”
- 严格模式下不允许删除变量的对象
Configurable = true 才可以删除变量对象
如果是严格模式下 以下代码会失效 以为不允许修改变量
var obj = { get x(){ return 0; } } obj.x = 3
- 严格模式下 eval不允许使用
- 混淆下基本都是非严格模式