JavaScript这门语言中,最令人迷惑的地方有三个,闭包、this、原型。针对大多数人,可以利用词法作用域等避开this的坑,但是我们不能一直生活在舒适区,要敢于打破砂锅问到底,对我们来说也是一种提升。
一、一般对this关键字的误解:
1、this指向函数自身
2、this指向函数词法作用域
我们可以看以下一段代码:
function test() { test.a = 1; this.a = 2; console.log(test.a); console.log(this.a); console.log(test.a === this.a); } test(); console.dir(test);
在上面这段代码中,我们在全局声明一个方法test,给test中的a属性赋值1,当前方法中的this中的a属性赋值2,加入this指向函数自身,那么test.a === this,a并且都等于2.
下面我们来看下这段代码的运行结果:
从上可以看出,scopes为全局作用域window,this也指向这里,虽然函数本身也是一个对象,但是this并不指向这里。
有一点我们一定要记住,this是在运行时进行绑定的,并不是在编写时绑定的,它的上下文取决于函数调用时的各种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。
既然this是在运行时绑定的,那我们有没有办法改变当前this的绑定,使其不指向window,而指向方法test呢?答案是肯定的,我们可以借助一些强制绑定方法,如call、apply、bind来改变this的指向,我们可以将代码改成下面这种方式:
function test() { test.a = 1; this.a = 2; console.log(test.a); console.log(this.a); console.log(test.a === this.a); } test.call(test); console.dir(test);
运行结果如下:
接下来我们看下this是否指向函数的词法作用域,以下有段比较有意思的代码:
function parent() { var a = 2; function child() { console.log(this.a) } child(); } parent();
假如this指向函数的词法作用域,那么child方法中的this.a应该是存在,实际上的执行结果如下:
实际上,在JavaScript内部,作用域确实和对象类似,可见的标识符都是它的属性。但是作用域“对象”无法通过JavaScript代码访问,它存在JavaScript引擎内部。所以每当你想要把this和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。
二、this的绑定规则
this的绑定规则大致分为以下几类:
2.1 默认绑定
2.2 隐式绑定
2.3 显式绑定
2.4 new绑定
2.1 默认绑定
上述示例中this的指向是指向window的,他们都有一个共同的特征,不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则
2.2 隐式绑定
隐式绑定首先需要考虑的规则就是调用位置是否有上下文对象,或者说是否被某个对象拥有或包含,例如:
这里的this就是指向对象obj。还有类似一些DOM事件的绑定,document.getElementById('xxx').addEventListener('click', function(){xxx});回调方法中的this是指向选择器选中的元素的。这种情况下可以简单的理解为this指向调用方法.前面的那个对象。
2.3 显式绑定
显示绑定在开发过程中运用的比较多,借助于这些显式绑定方法,可以直接改变当前方法的this指向,使得js语言非常的灵活。主要有call、apply和bind三种,基本使用如下:
function sum() { console.log(this.a + this.b); } var obj1 = { a: 1, b: 2 }; var test = sum.bind(obj1); sum.call(obj1); //3 sum.apply(obj1); //3 test(); //3
注意事项:
call && apply第一个参数接受的是this对象,call第二个参数以后可以接受字符串形式的参数,apply接受的是一个类数组/数组参数
将null || undefined作为this的绑定对象传入call/apply/bind时,这些值在调用时会被忽略,实际应用的是默认绑定规则
2.4 new绑定
JavaScript语言中的new操作符和其他面向对象语言中的new操作符不大一样,因为在JavaScript中没有对象的概念。所有的函数都可以使用new来调用,new的调用又称为构造函数调用。在构造函数调用过程中,会自动执行下面的操作。
1、创建(或者说构造)一个全新的对象
2、这个对象会被执行[[Prototype]]连接
3、这个新对象会绑定到函数调用的this
4、如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象
构造函数也是js中常用的一种设计模式,如以下代码:
function Test(a, b) { this.a = a; this.b = b; this.add = function() { debugger; console.log(this.a + this.b); } } var cc = new Test(1, 2); cc.add(); console.log(cc);
在new调用过程中,返回了一个新对象,并且该对象的this指向Test;
JavaScript,this
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]