---恢复内容开始---

一、this是什么东东?

  this是指包含它的函数作为方法被调用时所属的对象。这句话理解起来跟卵一样看不懂,但是如果你把它拆分开来变成这三句话后就好理解一点了。

  1.包含它的函数

  2.作为方法被调用时

  3.所属的对象

二、this的绑定规则

  1、默认绑定  

var x = ;
function num(){
this.x = ;
}
console.log(this.x);//
num();
console.log(this.x);//1 //当没有使用let或者var时,声明的变量是全局变量,指向window,
//在这一形态下,其函数内部的this是与全局作用域时一样,直接指向window,执行完num()后,更改了x的值,所以其形态 依然等价于window。
      function foo(){
      console.log(this.a)     }     var a = ;     foo(); //     console.log(this.document === document); // true     // 在浏览器中,全局对象为 window 对象:     console.log(this === window); // true     this.a = ;     console.log(window.a); //     this指向全局对象。在非严格模式中,当funcion被不带任何修饰的函数直接引用进行调用的,只能使用默认绑定,无法应用其他规则  

    

  2、隐式绑定

    先看两段例子   

function foo(){
console.log(this.a)
} var obj = {
a:,
foo:foo
} obj.foo() //2
//隐式绑定————调用位置使用obj上下文来引用函数,可以说函数被调用时obj对象“拥有”或者“包含”它,它就指向谁。
 
function foo(){
console.log(this.a)
} var obj2 = {
a:,
foo:foo
} var obj1 = {
   a:,
   obj2:obj2,
   foo:foo
}
obj1.foo() //2
obj1.obj2.foo() //42
//此时可以控制台查看obj1,obj2对象里究竟包含了什么
//当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象
//对象属性引用链中只有最后一层在调用位置中起作用

下面思考这一段会输出什么呢?

function foo(){
console.log(this.a)
} var obj = {
a:,
foo:foo
} var bar = obj.foo; //这里bar将引用foo函数本身,所以不带有函数对象的上下文,this会直接指向window
bar() //?

//为什么没有隐式绑定?这种情况称为隐式丢失。
//因为bar=obj.foo 而obj.foo指向foo 也就是bar = function foo(){console.log(this.a)} foo中的this指向window,
//在window中并没有对a进行定义,so,结果是undefined

接下来再看一段会是什么结果呢?(参数传递时的隐式赋值)

function foo(){
console.log(this.a)
} function doback(fn){
fn()
} var obj = {
a:,
foo:foo
} var a = 'global'; doback(obj.foo) //? 显然答案是global,但是为什么呢?请继续往下看! //隐式丢失--被隐式绑定的函数会丢失绑定对象然后应用默认绑定。
//最后函数执行 doback(obj.foo)时,会进行参数传递,也就是 fn = obj.foo,就和上一个例子一样了。既this指向的是window。

  

  3、显示绑定

function foo(){
console.log(this.a)
} var obj = {
a:
}
foo.call(obj) //2 //显式绑定--第一个参数是一个对象,接着在调用函数时将其绑定到this,通过foo.call(obj),我们可以在调用foo时强制把他的this绑定到obj上
function foo(){
console.log(this.a)
} var obj = {
a:
} var a = '3333333'; var bar = function(){
foo.call(obj)
}
bar() // 2
bar.call(window) //2

// 硬绑定后bar无论怎么调用,都不会影响foo函数的this绑定
// 通过创建函数bar(),并在内部调用foo.call(obj),强制把foo的this绑定到obj上。硬绑定的bar之后无论如何调用函数,都只会在obj上调用foo。
我们来看一下他的应用:
function foo(num) {
console.log( this.a, num);
return this.a + num;
} var obj = {
a:
}; var bar = function() {
return foo.call( obj, ...arguments ); // 将obj对象硬编码进去
   //return foo.apply( obj, arguments ); // 也可以使用apply将obj对象硬编码进去
};

var b = bar(  ); // 2 3
console.log( b ); //

function fn1(){
console.log();
}
function fn2(){
console.log();
} fn1.call(fn2); //输出 1 fn1.call.call(fn2); //输出 2 这个暂时没有搞懂,但是东鸽子大师中有讲解,感兴趣的小伙伴可以看看。

  

  4、new绑定

    我们不去深入了解构造函数,但要知道new来调用函数,或者说发生构造函数调用时,执行了哪些

    当代码 new foo(...) 执行时:

    (1) 创建一个新对象,它继承自foo.prototype.

    (2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);new foo 等同于 new foo(),只能用在不传递任何参数的情况。

    (3) 执行构造函数中的代码(为这个新对象添加属性) ;

    (4) 返回新对象, 那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。

function foo(a){
this.a = a;
} var bar = new foo(); //创建一个新对象bar,它继承了foo.prototype. 也就是bar这个对象有a这个属性,且传进去的是2,使用new来调用foo(..)时,会构造一个新对象,并把它绑定到foo(..)调用中的this上
console.log(bar.a) //2 

三、下面做一个小练习看看你学会了吗?

例一:

function foo(a){
console.log(this.a)
} var obj1 = {
a:,
foo:foo
} var obj2 = {
a:,
foo:foo
} obj1.foo() //?
obj2.foo() //? obj1.foo.call(obj2) //?
obj2.foo.call(obj1) //? 答案:
obj1.foo() //2 隐式绑定
obj2.foo() //3 隐式绑定 obj1.foo.call(obj2) //3 显式绑定
obj2.foo.call(obj1) //2 显式绑定
通过答案得出:显示绑定 > 隐式绑定
显示绑定优先级更高,所以在判断时 应当 优先考虑 是否 存在 显示绑定
例二:

function foo(someting){
this.a = someting
} var obj1 = {
foo:foo
}
var obj2 = {}
obj1.foo()
var bar = new obj1.foo()
console.log(obj1.a)//?
console.log(bar.a)//? 答案:
console.log(obj1.a) //2
console.log(bar.a) //4 通过答案得出: new绑定 > 隐式绑定
显示绑定优先级更高,所以在判断时 应当 优先考虑 是否 存在 new绑定
需要注意的是:new和call/apply无法一起使用,因此无法通过new foo.call(obj)来直接测试

function foo(someting){
this.a = someting
} var obj1 = {} var bar = foo.bind(obj1) //不知道bind()方法的同学可以直接点击此处查看最骚的就是你同学贡献的详解。
bar()
console.log(obj1.a)//? var baz = new bar()
console.log(obj1.a)//?
console.log(baz.a)//? 答案:2 2 3 通过答案得出:new绑定 > 显示绑定
new修改了硬绑定调用bar(..)中的this,因为使用了new绑定,得到了一个名字为baz的新对象,并且baz.a的值为3.
所以 new绑定 > 显示绑定 > 隐式绑定 > 默认绑定

在此特别鸣谢同事Jason大哥的share!!!

---恢复内容结束---

关于JavaScript中this的指向,你知晓几分?请速来围观!的更多相关文章

  1. 关于Number的属性和方法你知晓几分?速来围观!

    1.Number.isFinite() 方法用来检测传入的参数是否是一个有穷数(finite number)返回值为布尔值. 和全局的 isFinite() 函数相比,这个方法不会强制将一个非数值的参 ...

  2. javascript中this的指向

    作为一个前端小白在开发中对于this的指向问题有时候总是会模糊,于是花时间研究了一番. 首先this是JS的关键字,this是js函数在运行是生成的一个内部对象,生成的这个this只能在函数内部使用. ...

  3. Javascript中的this指向。

    一.JavaScript中的函数 在了解this指向之前,要先弄明白函数执行时它的执行环境是如何创建的,这样可以更清楚的去理解JavaScript中的this指向. function fn(x,y,n ...

  4. JavaScript中 this 的指向

    很多人都会被JavaScript中this的指向(也就是函数在调用时的调用上下文)弄晕,这里做一下总结: 首先,顶层的this指向全局对象. 函数中的this按照调用方法的不同,其指向也不同: 1.函 ...

  5. 前端面试之JavaScript中this的指向【待完善!】

    JavaScript中this的指向问题! 另一个特殊的对象是 this,它在标准函数和箭头函数中有不同的行为. 在标准函数中, this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 t ...

  6. JavaScript中的this指向

    this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...

  7. Javascript 中的this 指向的对象,你搞清楚了吗?

    Javascript 中的this 总让人感到困惑,你能分清以下三种test1(),test2(),test3() 情况下的输出吗? 注:以下Javascript运行环境中为浏览器 //1 this在 ...

  8. javascript中的this指向问题

    在深入学习JavaScript之后,我们越来越多的会遇到函数或者在对象内部中,对于this的指向问题的疑惑,其实基本上每一个编程语言中都有一个this,这个this的指向都是大同小异,你也可以汉化它的 ...

  9. 谈谈 JavaScript 中的 this 指向问题

    JavaScript 中的 this 为一个重难点,它不像静态语言 C#.Java 一样,就表示当前对象.而在 JS 中, this 是运行时确定,而并非定义时就已确定其值. 谈起 this ,必须少 ...

随机推荐

  1. uva 11624 Fire! 【 BFS 】

    按白书上说的,先用一次bfs,求出每个点起火的时间 再bfs一次求出是否能够走出迷宫 #include<cstdio> #include<cstring> #include&l ...

  2. HDU 2669 Romantic( 拓欧水 )

    链接:传送门 题意:求解方程 X * a + Y * b = 1 的一组最小非负 X 的解,如果无解输出 "sorry" 思路:裸 exgcd /***************** ...

  3. [剑指offer] 1. 二维数组中的查找 (数组)

    注意是有序数组!! 思路: 1.利用二维数组由上到下,由左到右递增的规律,选取右上角或者左下角的元素a[m][n]与target进行比较, 当target小于元素a[m][n]时,那么target必定 ...

  4. [luogu] P3745 [六省联考2017]期末考试 (贪心)

    P3745 [六省联考2017]期末考试 题目描述 有 \(n\) 位同学,每位同学都参加了全部的 \(m\) 门课程的期末考试,都在焦急的等待成绩的公布. 第 \(i\) 位同学希望在第 \(t_i ...

  5. [luogu] P2354 [NOI2014]随机数生成器 (贪心)

    Description Input 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子.第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M ...

  6. 引入拦截器及swagger支持及解决redis无法初始化问题

    Springboot引入拦截器 自定义的拦截器类 Interceptor package cn.zytao.taosir.auth.config; import javax.annotation.Re ...

  7. cogs 2056. 无平方因子数

    2056. 无平方因子数 ★☆   输入文件:non.in   输出文件:non.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 给出正整数n,m,区间[n,m]内的无 ...

  8. Unsupported major.minor version 51.0问题的解决

    在java编程的过程中,当用myeclipse软件打开别人写的代码时,遇到Unsupported major.minor version 51.0此类问题,实在是令人痛苦不堪.弄了整整一晚才搞清楚,我 ...

  9. scikit-learn:3.5. Validation curves: plotting scores to evaluate models

    參考:http://scikit-learn.org/stable/modules/learning_curve.html estimator's generalization error can b ...

  10. LeetCode -- 求字符串数组中的最长公共前缀

    题目描写叙述: Write a function to find the longest common prefix string amongst an array of strings.就是给定1个 ...