本文共 2265 字,大约阅读时间需要 7 分钟。
js中的this在揭开面纱之前就是一个迷,每每遇到我都有些头痛。今天总结了下js中的this指向:
分类
- 默认绑定 --直接上级对象 严格模式下没有Windows 而是 undefined–
- 隐性绑定 --一般作为一个对象的方法,按照上级规则就是这个对象
- 显示绑定 --使用
apply() call() bind()
函数可以给函数显示绑定this指向的对象 - new – 使用new时函数里面的this会被改写指向this所在函数的对象。
上面 优先级是 4>3>2>1
具体实现:
- 默认绑定: 考虑下面代码:
function foo(){ var a = 1 ; console.log(this.a); // 10}var a = 10;foo();
这种就是典型的默认绑定,我们看看foo调用的位置,”光杆司令“,像 这种直接使用而不带任何修饰的函数调用 ,就 默认且只能 应用 默认绑定。
那默认绑定到哪呢,一般是window上,严格模式下 是undefined。
- 隐性绑定;
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();, 上下文取函数的直接上级,即紧挨着的那个,或者说对象链的最后一个。
- 显示绑定
这里我们就要用到 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!