js中this(二)

xiaoxiao2021-02-28  101

判断this指向的关键点:

1. 函数调用,this等于window

2. 对象方法调用时,this等于那个对象。

3. 匿名函数的执行环境具有全局性,因此其this对象通常指向window

4. call、apply、bind,new等会改变this指向

5. 多次调用,this指向直接调用方法的对象

例:

哪个对象调用了方法,该方法的this就指向那个对象

多次调用,this指向直接调用方法的对象

var a = 3; function foo(){ console.log(this.a) } var obj = { a: 2, foo: foo }; var obj1 = { a: 3, obj2: obj } obj.foo(); // 2 ; 对象方法调用:因为是obj调用的foo,所以foo的this指向了obj obj1.obj2.foo(); // 2 ;对象方法调用:多次调用时,this指向直接调用方法的对象

例:

找准关系,理解obj.foo(获取属性值)和obj.foo()(执行对象方法) var a = "obj"; function foo() { console.log( this.a ) } var obj = { a: 2, foo: foo } var obj2 = obj.foo; obj2(); // "obj" ; 函数调用:因为obj2引用的是foo函数本身,obj2()是一个函数调用,因此this指向window // =========================== var obj = { a: "blue" }; function foo() { return this.a; } obj.foo = foo; console.log(obj.foo()); // blue; 对象方法调用:obj.foo指向了foo,但是obj.foo()是对象调用了方法

例:

找准是函数调用还是方法调用 function foo () { console.log(this.a) } function doFoo (fn) { fn(); } var obj = { a: 2, foo: foo } var a = "obj"; doFoo(obj.foo); // obj ; 函数调用:尽管来回引用多次,但是最后是foo的函数调用

四、闭包

var color = "red"; var obj = { color: "blue", sayColor: function () { // var that = this; 将this保存,传递到匿名内。 console.log(this.color); return function () { // return that.color return this.color; }; } } console.log(obj.sayColor()()); // blue red // obj.sayColor()对象方法调用:返回了一个匿名函数,后面跟上一个(),进行了函数调用(匿名函数一般指向window)

五、call()与apply()方法作用相同,区别仅仅在于接收参数方式不同

call(this, arg1, arg2) & apply(this,arguments) & apply(this,[arg1,arg2,…argn])

function add(num1, num2) { return num1 + num2; } function callAdd(num1, num2) { return add.apply(this, arguments); } function callAdd1(num1, num2) { return add.apply(this, [num1, num2]); } // function callAdd1(num1, num2) { // return add.call(this, num1, num2); // } console.log(callAdd(10, 10)); // 20 console.log(callAdd1(10, 10)); // 20

类似于:

obj.m = foo; // 将foo存储为obj的临时方法 o.m(); // 调用它,不传入参数 delete o.m; // 将临时方法删除

call()和apply()能扩充函数赖以运行的作用域,使对象不需要与方法有任何耦合关系。传入obj对象后,this指向obj

var obj = { color: "blue" }; function sayColor() { console.log(this.color); } sayColor.call(obj);

apply的巧用:

// 返回数组中最大值。 function getMax2(arr){ return Math.max.apply(null,arr); } // 将数组转化为参数 function f(x, y, z) { // ... } var args = [0, 1, 2]; f.apply(null, args); // 将一个数组添加到另一个数组 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; Array.prototype.push.apply(arr1, arr2)

六、bind() 传入对下obj,this指向obj

var obj = { color: "blue" }; function sayColor() { console.log(this.color); } var objSayColor = sayColor.bind(obj); objSayColor();//blue

七、new

function A(name){ this.name = name; this.getName = function(){ console.log(this.name); } } var a = new A('testa'); console.dir(a) console.dir(A)

__proto__ 是原型, prototype是函数默认的一个属性,它指向一个对象,这个对象的constructor属性指向函数本身。

var a = new A(‘testa’)做了什么:

var o = new Object();

o. __proto__ = A.prototype;     function里面的默认的属性prototype

A.call(o)     这里this是指向o,可以把什么this.name/getName绑定到o上.

把这个o返回给a;      var a = new A()的过程.

如果返回(return)一个原始类型(无return时其实为return原始类型undefined)或返回值是5种基本型(Undefined类型、Null类型、Boolean类型、Number类型、String类型)之一,那么就返回new创建的匿名对象。

function A(name){ this.name = name; return 3 } var a = new A('testa'); console.log(a) // A{name: "testa"}

只要new表达式之后的constructor返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象

function A(name){ this.name = name; return { b: 3 } } var a = new A('testa'); console.log(a) // Object{b: 3}
转载请注明原文地址: https://www.6miu.com/read-22764.html

最新回复(0)