揭开面纱之-- js中的this
发布日期:2021-06-20 05:37:31 浏览次数:12 分类:技术文章

本文共 2265 字,大约阅读时间需要 7 分钟。

js中的this在揭开面纱之前就是一个迷,每每遇到我都有些头痛。今天总结了下js中的this指向:

分类

  1. 默认绑定 --直接上级对象 严格模式下没有Windows 而是 undefined–
  2. 隐性绑定 --一般作为一个对象的方法,按照上级规则就是这个对象
  3. 显示绑定 --使用apply() call() bind()函数可以给函数显示绑定this指向的对象
  4. new – 使用new时函数里面的this会被改写指向this所在函数的对象。

上面 优先级是 4>3>2>1

具体实现:

  1. 默认绑定:
    考虑下面代码:
function foo(){    var a = 1 ;    console.log(this.a);    // 10}var a = 10;foo();

这种就是典型的默认绑定,我们看看foo调用的位置,”光杆司令“,像 这种直接使用而不带任何修饰的函数调用 ,就 默认且只能 应用 默认绑定。

那默认绑定到哪呢,一般是window上,严格模式下 是undefined。

  1. 隐性绑定;
function foo(){    console.log(this.a);}var obj = {    a : 10,    foo : foo}foo();                // ?obj.foo();            // ?

答案 : undefined 10

foo()的这个写法熟悉吗,就是我们刚刚写的默认绑定,等价于打印window.a,故输出undefined ,下面obj.foo()这种大家应该经常写,这其实就是我们马上要讨论的 隐性绑定 。函数foo执行的时候有了上下文对象,即 obj。这种情况下,函数里的this默认绑定为上下文对象,等价于打印obj.a,故输出10 。如果是链性的关系,比如 xx.yy.obj.foo();, 上下文取函数的直接上级,即紧挨着的那个,或者说对象链的最后一个。

  1. 显示绑定

这里我们就要用到 js 给我们提供的函数 call 和 apply,它们的作用都是改变函数的this指向,第一个参数都是 设置this对象。两个函数的区别:

call从第二个参数开始所有的参数都是 原函数的参数。
apply只接受两个参数,且第二个参数必须是数组,这个数组代表原函数的参数列表。例如:

function foo(a,b){    console.log(a+b);}foo.call(null,'海洋','饼干');        // 海洋饼干  这里this指向不重要就写null了foo.apply(null, ['海洋','饼干'] );     // 海洋饼干

除了 call,apply函数以外,还有一个改变this的函数 bind ,它和call,apply都不同。

bind只有一个函数,且不会立刻执行__,只是将一个值绑定到函数的this上,并将绑定好的函数返回。例:

function foo(){    console.log(this.a);}var obj = { a : 10 };foo = foo.bind(obj);foo();                    // 10

什么是new?

学过面向对象的小伙伴对new肯定不陌生,js的new和传统的面向对象语言的new的作用都是创建一个新的对象,但是他们的机制完全不同。创建一个新对象少不了一个概念,那就是构造函数,传统的面向对象 构造函数 是类里的一种特殊函数,要创建对象时使用new 类名()的形式去调用类中的构造函数,而js中就不一样了。js中的只要用new修饰的 函数就是’构造函数’,准确来说是 函数的构造调用,因为在js中并不存在所谓的’构造函数’。那么用new 做到函数的构造调用后,js帮我们做了什么工作呢:

  • 创建一个新对象
  • 把这个新对象的__proto__属性指向 原函数的prototype属性。(即继承原函数的原型)
  • 将这个新对象绑定到 此函数的this上 。
  • 返回新对象,如果这个函数没有返回其他对象。

第三条就是我们下面要聊的new绑定

4. new 绑定

function foo(){    this.a = 10;    console.log(this);}foo();                    // window对象console.log(window.a);    // 10   默认绑定var obj = new foo();      // foo{ a : 10 }  创建的新对象的默认名为函数名                          // 然后等价于 foo { a : 10 };  var obj = foo;console.log(obj.a);       // 10    new绑定

使用new调用函数后,函数会 以自己的名字 命名 和 创建 一个新的对象,并返回。

特别注意 : 如果原函数返回一个对象类型,那么将无法返回新对象,你将丢失绑定this的新对象,例:

function foo(){    this.a = 10;    return new String("捣蛋鬼");}var obj = new foo();console.log(obj.a);       // undefinedconsole.log(obj);         // "捣蛋鬼"

转载地址:https://blog.csdn.net/h2453532874/article/details/94895378 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Sql 语句的对比 -- REPLACE INTO 、 INSERT ON DUPLICATE KEY UPDATE 、 INSERT IGNORE INTO
下一篇:lombok 的var 使用时报错

发表评论

最新留言

很好
[***.229.124.182]2024年04月17日 05时52分09秒