-
Notifications
You must be signed in to change notification settings - Fork 52
再探this指向
LYF edited this page Jun 3, 2020
·
15 revisions
var property = "window property";
function test(){
this.property = "test object property";
}
test.property = "test function property";
var fn = test.fn = test.property.fn = function(){
alert(this.property);
}
fn(); // window property
test.fn(); // test function property
var t = new test();
alert(t.property); // test object property
var property = "window property";
var obj = {
property:"obj property",
sayProperty:function(){
alert(this.property);
}
}
obj.sayProperty(); // obj property
var fn = obj.sayProperty;
fn(); // window property
(obj.sayProperty)(); // obj property
// 如果不适用严格模式,那么两个函数内部的this都是指向window的
"use strict";
(function(){
console.log("IIFE inner",this); // undefined
function test(){
console.log("this inner",this) // undefined
}
test();
})()
箭头函数没有自己的this绑定,绑定的是父函数内的this,也就是说,只有父函数的this改变,箭头函数的this才改变,我们无法直接改变箭头函数的this指向
例如
var name = 'window'
var obj = {
name: 'obj'
}
function parentFunction () {
return () => console.log(this.name)
}
parentFunction()() // window
var innerFunction1 = parentFunction()
innerFunction1() // window
// 无法改变this指向
parentFunction().call(obj) // window
// 无法改变this指向
var innerFunction2 = parentFunction().bind(obj)
innerFunction2() // window
// 我们来试试改变外部函数的this指向
var innerFunction3 = parentFunction.call(obj)
// 改变了外部函数this指向,箭头函数的this也跟着变了
innerFunction3() // obj
// 再试试bind,发现也是同上
var innerFunction4 = parentFunction.bind(obj)()
innerFunction4() // obj
- 普通函数调用,this为全局对象或是undefined
- 作为对象的方法,this为那个对象
- new 表达式,this为以该函数为原型的新创建的对象
- 使用 apply/call指定 this
- 用bind绑定固定的this
- 事件处理函数中的this是当前的触发事件的DOM元素(event.currentTarget)
- this跟代码中的位置没关系,是在执行的时候赋值的
- this是不会沿着变量作用域、原型链或闭包结构向上查找
-
this只存在于函数调用期间,在变量作用域中不存在跟第
7
条是一个意思,这里列出来,是为了在不同的语境下理解
var length = 10;
function fn(){
alert(this.length);
}
var obj = {
length:5,
method:function( fn /* , a */ ){
fn(); // 10
arguments[0](); //1
// this.method.arguments[0]();
// console.dir(arguments);
// console.dir(this.method.length);
// console.dir(arguments.length);
}
}
obj.method(fn);
第一个弹出10应该好理解,第二个弹出1 arguments并不是一个数组 arguments[0]这个0就相当于arguments的一个属性,跟obj[attrName]是一样的 arguments0就跟调用obj[attrName]一样,这时候fn里面的this就指向arguments了 这样就能理解后一个为什么是1了
https://segmentfault.com/q/1010000004867221?_ea=712571
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
var name = 'window'
var person1 = {
name: 'person1',
show1: function () {
console.log(this.name)
},
show2: () => console.log(this.name),
show3: function () {
return function () {
console.log(this.name)
}
},
show4: function () {
return () => console.log(this.name)
}
}
var person2 = { name: 'person2' }
person1.show1()
person1.show1.call(person2)
person1.show2()
person1.show2.call(person2)
person1.show3()()
person1.show3().call(person2)
person1.show3.call(person2)()
person1.show4()()
person1.show4().call(person2)
person1.show4.call(person2)()
var name = 'window'
function Person (name) {
this.name = name;
this.show1 = function () {
console.log(this.name)
}
this.show2 = () => console.log(this.name)
this.show3 = function () {
return function () {
console.log(this.name)
}
}
this.show4 = function () {
return () => console.log(this.name)
}
}
var personA = new Person('personA')
var personB = new Person('personB')
personA.show1()
personA.show1.call(personB)
personA.show2()
personA.show2.call(personB)
personA.show3()()
personA.show3().call(personB)
personA.show3.call(personB)()
personA.show4()()
personA.show4().call(personB)
personA.show4.call(personB)()
默认绑定(非严格模式情况下,this 指向 window, 严格模式下,this指向 undefined。) 隐式绑定(如果函数调用时,前面存在调用它的对象,那么this就会隐式绑定到这个对象上) 显式绑定(函数通过 call()、apply()、bind()调用,this 指向被绑定的对象。) new 绑定(函数被 new 调用,this 指向由 new 新构造出来的这个对象。)
绑定优先级:
new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定
function globalFunction() {
this.a = 'globalFunction';
}
let obj = {
name: 'obj'
};
// 1、bind
const Bar = globalFunction.bind(obj);
// 2、new
const bar = new Bar();
console.log(obj.a, '--', bar.a) // obj -- globalFunction
https://juejin.im/post/5e88b054f265da47c35d7418
构造函数内的this
指向,是指向new
操作符产生的对象的,由于箭头函数没有自己的this
绑定,所以无法使用当成构造器使用它,会报TypeError
var Person = () => { this.name = name; }
var p = new Person()
VM386:1 Uncaught TypeError: Person is not a constructor
at <anonymous>:1:9