JavaScript的this学习笔记
来源:互联网 发布:cad软件锁不起作用 编辑:程序博客网 时间:2024/05/18 01:33
1 浏览器宿主的全局环境中,this指的是window对象
2 浏览器中在全局环境下,使用var声明变量其实就是赋值给this或window
3 任何情况下,创建变量时没有使用var或者let(ECMAScript 6),也是在操作全局this
foo = "bar"; function testThis() { foo = "foo"; } console.log(this.foo); //logs "bar" testThis(); console.log(this.foo); //logs "foo"
4 除了DOM的事件回调或者提供了执行上下文的情况,函数正常被调用(不带new)时,里面的this指向的是全局作用域
foo = "bar"; function testThis() { this.foo = "foo"; } console.log(this.foo); //logs "bar" testThis(); console.log(this.foo); //logs "foo"
5 当用调用函数时使用了new关键字,此刻this指代一个新的上下文,不再指向全局this
foo = "bar"; function testThis() { this.foo = "foo"; } console.log(this.foo); //logs "bar" new testThis(); console.log(this.foo); //logs "bar" console.log(new testThis().foo); //logs "foo"
6 当通过new的方式创建了多个实例后,他们会共用一个原型,直到this.xxx被重写
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { console.log(this.foo);}Thing.prototype.setFoo = function (newFoo) { this.foo = newFoo;}var thing1 = new Thing();var thing2 = new Thing();thing1.logFoo(); //logs "bar"thing2.logFoo(); //logs "bar"thing1.setFoo("foo");thing1.logFoo(); //logs "foo";thing2.logFoo(); //logs "bar";thing2.foo = "foobar";thing1.logFoo(); //logs "foo";thing2.logFoo(); //logs "foobar";
7 在实例中,this是个特殊的对象,而this自身其实只是个关键字。可以把this想象成在实例中获取原型值的一种途径,同时对this赋值又会覆盖原型上的值。完全可以将新增的值从原型中删除从而将原型还原为初始状态
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { console.log(this.foo);}Thing.prototype.setFoo = function (newFoo) { this.foo = newFoo;}Thing.prototype.deleteFoo = function () { delete this.foo;}var thing = new Thing();thing.setFoo("foo");thing.logFoo(); //logs "foo";thing.deleteFoo();thing.logFoo(); //logs "bar";
8 不通过实例,直接操作函数的原型
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { console.log(this.foo, Thing.prototype.foo);}var thing = new Thing();thing.foo = "foo";thing.logFoo(); //logs "foo bar"; this是获取原型值的一个途径 改变的是值的指向而没有直接改变了值
9 同一函数创建的所有实例均共享一个原型。如果给原型赋值了一个数组,那么所有实例都能获取到这个数组。除非你在某个实例中对其进行了重写,实际上是进行了覆盖
function Thing() {}Thing.prototype.things = [];var thing1 = new Thing();var thing2 = new Thing();thing1.things.push("foo");console.log(thing2.things); //logs ["foo"]
通常上面的做法是不正确的(改变thing1的同时也影响了thing2)。如果想每个实例互不影响,那么在函数里创建这些值,而不是在原型上。
function Thing() { this.things = [];}var thing1 = new Thing();var thing2 = new Thing();thing1.things.push("foo");console.log(thing1.things); //logs ["foo"]console.log(thing2.things); //logs []
10 多个函数可以形成原型链,这样this便会在原型链上逐步往上找直到找到想引用的值
function Thing1() {}Thing1.prototype.foo = "bar";function Thing2() {}Thing2.prototype = new Thing1();var thing = new Thing2();console.log(thing.foo); //logs "bar"
注意原型链底层函数中对this的操作会覆盖上层的值
function Thing1() {}Thing1.prototype.foo = "bar";function Thing2() { this.foo = "foo";}Thing2.prototype = new Thing1();function Thing3() {}Thing3.prototype = new Thing2();var thing = new Thing3();console.log(thing.foo); //logs "foo"
11 原型链方法中的this是从实例中的this开始住上查找整个原型链的。也就是说,如果原型链中某个地方直接对this进行赋值覆盖了某个变量,那么我们拿到 的是覆盖后的值。
function Thing1() {}Thing1.prototype.foo = "bar";Thing1.prototype.logFoo = function () { console.log(this.foo);}function Thing2() { this.foo = "foo";}Thing2.prototype = new Thing1();var thing = new Thing2();thing.logFoo(); //logs "foo";
12 在JavaScript中,函数可以嵌套函数,也就是可以在函数里面继续定义函数。但内层函数是通过闭包获取外层函数里定义的变量值的,而不是直接继承this
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { var info = "attempting to log this.foo:"; function doIt() { console.log(info, this.foo); } doIt();}var thing = new Thing();thing.logFoo(); //logs "attempting to log this.foo: undefined"//将this缓存起来,用个叫self或者其他什么的变量来保存,以将外层与内层的this区分开来function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { var self = this; var info = "attempting to log this.foo:"; function doIt() { console.log(info, self.foo); } doIt();}var thing = new Thing();thing.logFoo(); //logs "attempting to log this.foo: bar"
13 但把实例的方法作为参数传递时,实例是不会跟着过去的。也就是说,此时方法中的this在调用时指向的是全局this
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { console.log(this.foo); }function doIt(method) { method();}var thing = new Thing();thing.logFoo(); //logs "bar"doIt(thing.logFoo); //logs undefined
解决方法就是传递的时候使用bind方法显示指明上下文,bind方法是所有函数或方法都具有的
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { console.log(this.foo);}function doIt(method) { method();}var thing = new Thing();doIt(thing.logFoo.bind(thing)); //logs bar
同时也可以使用apply或call 来调用该方法或函数,让它在一个新的上下文中执行。
function Thing() {}Thing.prototype.foo = "bar";Thing.prototype.logFoo = function () { function doIt() { console.log(this.foo); } doIt.apply(this);}function doItIndirectly(method) { method();}var thing = new Thing();doItIndirectly(thing.logFoo.bind(thing)); //logs bar
14 使用bind可以任意改变函数或方法的执行上下文,即使它没有被绑定到一个实例的原型上
function Thing() {}Thing.prototype.foo = "bar";function logFoo(aStr) { console.log(aStr, this.foo);}var thing = new Thing();logFoo.bind(thing)("using bind"); //logs "using bind bar"logFoo.apply(thing, ["using apply"]); //logs "using apply bar"logFoo.call(thing, "using call"); //logs "using call bar"logFoo("using nothing"); //logs "using nothing undefined"
15 对象中的this
可以在对象的任何方法中使用this来访问该对象的属性。这与用new得到的实例是不一样的
var obj = { foo: "bar", logFoo: function () { console.log(this.foo); }};obj.logFoo(); //logs "bar"
通过this所拿到的只是该对象身上的属性而已
var obj = { foo: "bar", deeper: { logFoo: function () { console.log(this.foo); } }};obj.deeper.logFoo(); //logs undefined
也可以不通过this,直接访问对象的属性
var obj = { foo: "bar", deeper: { logFoo: function () { console.log(obj.foo); } }};obj.deeper.logFoo(); //logs "bar"
- JavaScript的this学习笔记
- 学习笔记---javascript的this问题
- JavaScript 中 关于 this 的学习笔记
- JavaScript学习笔记5-Javascript的this用法
- JavaScript学习笔记(3)---this
- JavaScript中的this学习笔记
- JavaScript之this学习笔记
- javascript中this,apply,call,bind的学习笔记
- JavaScript 学习笔记 四 this指针
- javascript学习笔记——this对象
- Javascript闭包和this学习笔记
- JavaScript学习笔记-04this绑定
- 学习笔记 jquery的this
- JavaScript笔记1--this的含义
- Java程序员的JavaScript学习笔记(3——this/call/apply)
- 零基础入门-javaScript学习笔记之对象和不一样的this
- 学习JavaScript遇到的this问题
- JavaScript学习--Item21 漂移的this
- jdk环境配置
- 软件工程(C编码实践篇)学习总结
- android获取系统标准时区的时间
- VBA基础打卡
- 简单的桃心,haha
- JavaScript的this学习笔记
- 11.13学习心得
- 变量
- 【PAT Practise】1014. Waiting in Line (30)
- C++primer习题第五章
- vue-cli及vue-router(一)
- hdu2819-Swap(二分图匹配,思路)
- file_operations结构体
- 物联网基础之了解CCP协议,COAP协议,MTQQ协议等