课堂课题:
简述JS中this的指向
关联任务:
任务二
直播时间:
2019-09-08 15:00:00
课堂内容:
视频链接:
PPT链接:
提交按钮:
小课堂内容格式
标题:
【修真院xx(职业)小课堂】课题名称
开场语:
大家好,我是IT修真院XX分院第X期的学员XX,一枚正直纯洁善良的XX程序员,今天给大家分享一下,修真院官网XX(职业)任务X,深度思考中的知识点——XXX
(1)背景介绍:
背景介绍的时候,尽可能的要宽广,讲清楚来龙去脉,讲清楚为什么会需要这个技术。
(2)知识剖析:
讲知识点的时候,尽可能的成体系,学会成体系的去给别人介绍知识。现在很多做的都是零散的,没有分类。
(3)常见问题:
最少列出1个常见问题。
(4)解决方案:
写清楚常见问题的解决方案。
(5)编码实战:
尽可能的去寻找在真实项目中在用的。如果你能找到某个网站在用你说的知识点,这是最好的。学以致用,否则当成练习题就没有意义了。多准备一些demo,讲解过程中将知识点和demo结合,便于大家理解所讲解的知识点。
(6)拓展思考:
知识点之外的拓展思考,由分享人进行讲解,这些东西就是所谓的深度,也是一个人技术水准高低比较的表现。
(7)参考文献:
引入参加文献的时候,在引用的句子后面加上序号【1】。参考文献中列出详细来源。不要去抄别人的东西,这是一个基本的态度。
(8)更多讨论:
Q1:提问人:问题?
A1:回答人(可以是分享人,也可以是其他学员):回答
Q2:提问人:问题?
A2:回答人(可以是分享人,也可以是其他学员):回答
Q3:提问人:问题?
A3:回答人(可以是分享人,也可以是其他学员):回答
(9)鸣谢:
感谢XX、XX师兄,此教程是在他们之前技术分享的基础上完善而成。
(10)结束语:
今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~
修真院web小课堂】简述js中this的指向
大家好,我是IT修真院北京分院第40期的学员姚富成,今天给大家分享一下,深度思考中的知识点——简述js中this的指向
1、背景介绍
js 的 this 是个比较令人头疼的东西,尤其是在面试的时候,深受面试官的喜爱。我们今天来谈谈 js 中的 this
this是什么
理解this之前, 先纠正一个观点,this既不指向函数自身,也不指函数的词法作用域。如果仅通过this的英文解释,太容易产生误导了。它实际是在函数被调用时才发生的绑定,也就是说this具体指向什么,取决于你是怎么调用的函数。
为什么要用this
this机制提供了更优雅的方式来隐含地“传递”一个对象引用,导致更加干净的 API 设计和更容易的复用。当我们的代码和使用环境约复杂,我们就越能感受到 this的重要性
2、知识剖析
this 绑定规则
this的4种绑定规则分别是:默认绑定、隐式绑定、显示绑定、new 绑定。优先级从低到高
默认绑定
什么叫默认绑定,即没有其他绑定规则存在时的默认规则。这也是函数调用中最常用的规则。
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(); // undefined
obj.foo(); // 10
foo()的这个写法就是我们刚刚写的默认绑定,等价于打印window.a,故输出undefined ,。
下面obj.foo()这种大家应该经常写,这其实就是我们要讨论的隐性绑定 。
函数foo执行的时候有了上下文对象,即 obj。这种情况下,函数里的this默认绑定为上下文对象,等价于打印obj.a,故输出10 。
如果是链性的关系,比如 xx.yy.obj.foo();, 上下文取函数的直接上级,即紧挨着的那个,或者说对象链的最后一个。
隐式丢失(函数别名)
这里存在一个陷阱,大家在分析调用过程时,要特别小心
function foo() {
onsole.log( this.a );
}
var a = 2;
var obj = {
a: 3,
foo: foo
};
var bar = obj.foo;
bar(); //2
为什么bar() 打印的结果是2,obj.foo 赋值给bar,那调用bar()为什么没有触发隐式绑定,使用的是默认绑定呢
这里有个概念要理解清楚,obj.foo 是引用属性,赋值给bar的实际上就是foo函数(即:bar指向foo本身)。
那么,实际的调用关系是:通过bar找到foo函数,进行调用。整个调用过程并没有obj的参数,所以是默认绑定,全局属性a。
隐式丢失(回调函数)
function foo() {
console.log( this.a );
}
var a = 2;
var obj = {
a: 3,
foo: foo
};
setTimeout( obj.foo, 100 ); // 2
同样的道理,虽然参传是obj.foo,因为是引用关系,所以传参实际上传的就是foo对象本身的引用。对于setTimeout的调用,还是 setTimeout -> 获取参数中foo的引用参数 -> 执行foo 函数,中间没有obj的参与。这里依旧进行的是默认绑定。
显性绑定
隐性绑定的限制
在我们刚刚的 隐性绑定中有一个致命的限制,就是上下文必须包含我们的函数 ,例:var obj = { foo : foo},如果上下文不包含我们的函数用隐性绑定明显是要出错的,不可能每个对象都要加这个函数 ,那样的话扩展,维护性太差了,我们接下来聊的就是直接 给函数强制性绑定this。
call apply bind
这里我们就要用到 js 给我们提供的函数 call 和 apply,它们的作用都是改变函数的this指向,第一个参数都是 设置this对象。
function foo(a,b){
console.log(a+b);
}
foo.call(null,'海洋','饼干'); // 海洋饼干 这里this指向不重要就写null了
foo.apply(null, ['海洋','饼干'] ); // 海洋饼干
两个函数的区别:
call从第二个参数开始所有的参数都是 原函数的参数。
apply只接受两个参数,且第二个参数必须是数组,这个数组代表原函数的参数列表。
bind只有一个函数,且不会立刻执行,只是将一个值绑定到函数的this上,并将绑定好的函数返回。例:
function foo(){
console.log(this.a);
}
var obj = { a : 10 };
foo = foo.bind(obj);
foo(); //10
function foo(){
console.log(this.a);
}
ar obj = {
a : 10 //去掉里面的foo
}
foo.call(obj); // 10
将隐性绑定例子中的 上下文对象 里的函数去掉了,显然现在不能用 上下文.函数
这种形式来调用函数,大家看代码里的显性绑定代码foo.call(obj),看起来很怪,和我们之前所了解的函数调用不一样。
其实call 是 foo上的一个函数,在改变this指向的同时执行这个函数。
new 绑定
创建一个新对象少不了一个概念,那就是构造函数,传统的面向对象 构造函数 是类里的一种特殊函数,要创建对象时使用new 类名()的形式去调用类中的构造函数,而js中就不一样了。js中的只要用new修饰的 函数就是'构造函数',准确来说是 函数的构造调用,因为在js中并不存在所谓的'构造函数'。
>那么用new 做到函数的构造调用后,js帮我们做了什么工作呢:
创建一个新对象把这个新对象的__proto__属性指向 原函数的prototype属性。(即继承原函数的原型)将这个新对象绑定到 此函数的this上 。返回新对象,如果这个函数没有返回其他对象。
第三条就是我们下面要聊的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的新对象
unction foo(){
this.a = 10;
return new String("捣蛋鬼");
}
var obj = new foo();
console.log(obj.a); // undefined
console.log(obj); // "捣蛋鬼"
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
this绑定优先级
new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定
7.参考文献
https://segmentfault.com/a/1190000011194676
8.更多讨论
[北京|结业弟子]JS-肖明明 发表于 2019-10-07 09:18:01 #1
默认绑定,显示绑定,隐式绑定这种概念是不是多余的
回复