js基本操作-this理解

fania

js基本操作-this理解


写在前面

在面向对象的语言中,this关键字的含义是明确且具体的,即指代当前对象。一般在编译期确定下来,或称为编译期绑定。而在 JavaScript中,this是动态绑定,或称为运行期绑定的,这就导致JavaScript中的this关键字有能力具备多重含义,带来灵活性的同时,也为初学者带来不少困惑。

当然,还是老话,所有的方法都来自网上,学到了才是自己的!!

然后,写在前面,带上我们可爱的小伙伴。废话不多说,下面我们开始看起吧!
小伙伴

基本介绍

文章主要是对js的this进行简单的说明和介绍,顺带会添加一些代码,没办法,语言能力有限,说明不了的只能直接上代码了。

关于JS中的this,这是很多前端面试必考的题目,有时候在网上看到这些题目,看着感觉还不错,做起来非常的酸爽!而在实际的开发中,也会遇到各种使用this的问题。当然,在刚开始的时候,我们可能会非常的困惑,这个地方,为什么要这样使用this尼?有时候不明白为什么不直接使用this,而要把this作为参数传入。

下面,我将以我的理解的方式对this的理解和使用,做一个简单的介绍。

this的理解

接单的理解:this指的是引用它的对象。

当然,也可以套用轮子哥的一个解释:

this在js的函数里面只是一个参数,是通过Fuck.Shit(Bitches)这种语法来传递的,点号前面的表达式就算this。不要想太多。

一般来说,阐述JavaScript中this的运作机制,下面一句话诠释的非常贴切。

When a function of an object was called, the object will be passed into the execution context as this value

简而言之,就是function的this永远指向调用它的对象。而鉴于JS所谓的“万物皆对象”,这个this因此可以是任何物件,比如Global对象

JavaScript有一套完全不同于其它语言的对this的处理机制。 下面,将会在不同的情况下,this指向的各不相同。

1.全局范围内

当在全部范围内使用 this,它将会指向全局对象。

this;
console.log(this);//输出window

浏览器中运行的 JavaScript 脚本,这个全局对象是 window。

2.函数调用

这里this也会指向全局对象。

function foo(){
    console.log(this);
}
foo();//输出window

3.方法调用

这个例子中,this 指向调用方法的对象。

var test = {
    foo : function(){
        console.log(this);
    }
}
test.foo();//输出test对象

4.调用构造函数

如果函数倾向于和 new 关键词一块使用,则我们称这个函数是 构造函数。 在函数内部,this 指向新创建的对象。

function foo(name,age){
    this.name = name;
    this.age = age;
    console.log(this);
}
new foo('yu',23);//输出新创建的对象 foo {name: "yu", age: 23}

5.显式的设置

当使用Function.prototype上的call或者apply方法时,函数内的this将会被显式设置为函数调用的第一个参数。

因此函数调用的规则在上例中已经不适用了,在foo 函数内 this 被设置成了 bar。

function foo(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
}

var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,bar被修改为Object {a: 1, b: 2, c: 3}
foo.call(bar, 4, 4, 4); // 传递到foo的参数是:a = 4, b = 4, c = 4; bar被修改为Object {a: 4, b: 4, c: 4}

这里使用了apply和call方法,用于修改this指针的指向。会在后面的文章中详细说明。

使用用例

题目描述:
实现函数 callIt,调用之后满足如下条件
1、返回的结果为调用 fn 之后的结果
2、fn 的调用参数为 callIt 的第一个参数之后的全部参数

输入例子:

var a = 1; 
var b = 2; 
var test = function (first, second) { 
    return first === a && second === b;
}; 
callIt(test, a, b);

输出例子: true

代码实现

//方法一
function callIt(fn) {
    var arr = [].slice.call(arguments,1);
    return fn.call(null, arr[0], arr[1]);//因为只有两个参数,这里直接使用两个了
    // 
}
//方法二
function callIt(fn) {
    //Array.prototype.slice.call的作用是将arguments伪对象转换成数组对象。
    //下面的目的是,将arguments转化为数组后,截取第一个元素之后的所有元素
    return fn.apply(this,[].slice.call(arguments,1));//这里用[]代替Array.prototype,也可以使用下面的。
    //return fn.apply(this,Array.prototype.slice.call(arguments,1));
}

代码说明:

  • 首先,arguments不是真正的数组,不能直接使用slice方法,所以才会用Array对象原型链上面的slice方法去处理arguments,返回的自然是一个数组。

  • 另外,给apply/call传递null,“”空字符串,默认都是this


其他说明

  • 以上的所有方法,都来自网上。

  • 所有的方法,都必须脚踏实地,在具体应用场景下去分析、去选择,我们应该按照具体的情况,来选择方法。

  • 因为浏览器的多样性,前端的应用场景经常很复杂,性能优化充满挑战,也充满机遇。

  • 学会了才是自己的,知道会用会写,才是我们最终的目标。

参考文档

阅读 1.7k

fania
自己的学习分享,
63 声望
3 粉丝
0 条评论
63 声望
3 粉丝
文章目录
宣传栏