1. global this

2.function this

3.prototype this

4. object this

5.DOM this

6 HTML this

7 override this

8 with this

9 jQuery this

10 thisArg this

注意一点:

在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 指向的是全局的window对象!这种情况下,我们可以把this捕获到一个变量里面,通常这个变量叫做self,来避免上面这种情况的发生。

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"

  但是当你需要把一个方法作为一个值传递给一个函数的时候并不管用。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
var self = this;
function doIt() {
console.log(self.foo);
}
doIt();
} function doItIndirectly(method) {
method();
} var thing = new Thing();
thing.logFoo(); //logs "bar"
doItIndirectly(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

  你可以用bind来代替任何一个函数或者方法的this,即便它没有赋值给实例的初始prototype。

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"

  你应该避免在构造函数里面返回任何东西,因为这可能代替本来应该返回的实例。

function Thing() {
return {};
}
Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () {
console.log(this.foo);
} var thing = new Thing();
thing.logFoo(); //Uncaught TypeError: undefined is not a function

  奇怪的是,如果你在构造函数里面返回了一个原始值,上面所述的情况并不会发生并且返回语句被忽略了。最好不要在你将通过new调用的构造函数里面返回任何类型的数据,即便你知道自己正在做什么。如果你想创建一个工厂模式,通过一个函数来创建一个实例,这个时候不要使用new来调用函数。当然这个建议是可选的。

你可以通过使用Object.create来避免使用new,这样同样能够创建一个实例。

function Thing() {
}
Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () {
console.log(this.foo);
} var thing = Object.create(Thing.prototype);
thing.logFoo(); //logs "bar"

  

function Thing() {
this.foo = "foo";
}
Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () {
console.log(this.foo);
} var thing = Object.create(Thing.prototype);
thing.logFoo(); //logs "bar"

  因为Object.create不会调用构造函数的特性在你继承模式下你想通过原型链重写构造函数的时候非常有用

function Thing1() {
this.foo = "foo";
}
Thing1.prototype.foo = "bar"; function Thing2() {
this.logFoo(); //logs "bar"
Thing1.apply(this);
this.logFoo(); //logs "foo"
}
Thing2.prototype = Object.create(Thing1.prototype);
Thing2.prototype.logFoo = function () {
console.log(this.foo);
} var thing = new Thing2();

  

在浏览器里,在全局范围内,用var声明一个变量和给this或者window添加属性是等价的。”

楼主,这句话貌似不对,它们并不是完全等价的,你可以试下下面的例子:

var foo = 123;
window.bar = 345;
delete foo;
delete bar;
console.log(this.foo,this.bar)

这个您恐怕忽略了一点,属性是可以删除的,而变量是不能通过delete删除的,bar是属性,但是foo是变量,所以foo的值仍然存在,而bar被删除了,显示为undefined

javascript 中this的使用场景全的更多相关文章

  1. javascript中的this使用场景

    刚接触js不久时对this总是感到无比迷茫,以下是来自js设计模式与实践里的总结 this总是指向一个对象,有时指向全局对象,有时指向构造对象,有时指向DOM对象 1. 作为对象的方法调用 做为对象的 ...

  2. JavaScript中的this陷阱的最全收集 没有之一

    当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概 念,可能真解释不清楚.有句话这么说:如果你不能向一个6岁小孩解 ...

  3. 转:JavaScript中的this陷阱的最全收集

    在其他地方看到的,觉得解释的狠详细,特此分享 当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概念,可能真解释不清 ...

  4. JavaScript中常用的正则表达式日常整理(全)

    //校验是否全由数字组成 ? 1 2 3 4 5 6 function isDigit(s) { var patrn=/^[0-9]{1,20}$/; if (!patrn.exec(s)) retu ...

  5. JavaScript中“&&”和“||”操作符的意义,深入理解和使用场景

     一.概念 与其他语言不同,在js中,逻辑运算符可以返回任何类型的数据,不仅仅是true和false. &&和||的返回值是两个操作数的其中一个.即a&&b或者a||b ...

  6. C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断

    C#保留2位小数几种场景总结   场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...

  7. JavaScript中的this陷阱的最全收集

    JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值.事实并非如此,在JavaScript中,最 ...

  8. javascript中的this在不同场景下的区别

    javascript在初版的设计上存在失误,导致了这门语言在使用时,经验型写法并不能得到像其它几个流行语言一样预期.其中的this的使用就是一个典型. this在javascript中是由解释器注入的 ...

  9. JavaScript 中的数据类型

    Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...

随机推荐

  1. R语言笔记1--向量、数组、矩阵、数据框、列表

    注释:R语言是区分大小写的 1.向量 R语言中可以将各种向量赋值为一个变量,这种赋值操作符就是等号“=”,也可以使用“<-”. 1)产生向量 (1)函数c() 例如:x1=c(2,4,6,8,0 ...

  2. shell:crontab

    crontab */1 * * * * (cd /home/q/system/project; /usr/bin/lockf -t 0 /tmp/discuz_bbs_audit.lock /usr/ ...

  3. 安卓srcCompat弄死我了

    <ImageView android:layout_width="150dp" android:layout_height="120dp" app:src ...

  4. HttpHandler 实现文件下载

    一个浏览者发出的请求都是由实现了IHttpHandler接口的对象进行响应,由于下次访问不一定还是上次那个对象进行响应,上次响应完毕对象可能已经被销毁了,写的类变量值早就不存在了,因此不将状态信息保存 ...

  5. IOS传值之Block传值(二)

    @interface QWViewController : UIViewController @property(nonatomic,strong)UILabel *label; @property( ...

  6. mysql 连接两列

    以下划线符号,连接两列,作为查询结果: SELECT CONCAT(col_1,'_',col_2) FROM yourtable

  7. Sql server 开窗函数over()的语法

    用法一:与ROW_NUMBER()函数结合用,给结果进行排序编号,如图: 代码如下: SELECT ROW_NUMBER() over(order by RequiredDate) num ,* fr ...

  8. cakephp2.3.0 lib中的Model.php有一个bug

    1. cakephp2.3.0 lib中的Model.php有一个bug, 加上 !empty($db->config['prefix']) 这个判断更好.有时候会少进行一次 new PDO() ...

  9. calc()使用笔记

    calc()可以给元素做运算, calc(expression) eg: .a { width: -webkit-calc(100% - 2px); width: -moz-calc(100% - 2 ...

  10. pom 的scope标签分析

    一.compile:编译范围compile是默认的范围:如果没有提供一个范围,编译范围依赖在所有的classpath 中可用,同时它们也会被打包.而且这些dependency会传递到依赖的项目中. 二 ...