js中this(二)

判断this指向的关键点:

1. 函数调用,this等于window

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

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

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

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

例:

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

  2. 多次调用,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指向直接调用方法的对象

例:

  1. 找准关系,理解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()是对象调用了方法

例:

  1. 找准是函数调用还是方法调用
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’)做了什么:

  1. var o = new Object();

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

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

  4. 把这个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}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值