javascript 中this的使用场景全
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的使用场景全的更多相关文章
- javascript中的this使用场景
刚接触js不久时对this总是感到无比迷茫,以下是来自js设计模式与实践里的总结 this总是指向一个对象,有时指向全局对象,有时指向构造对象,有时指向DOM对象 1. 作为对象的方法调用 做为对象的 ...
- JavaScript中的this陷阱的最全收集 没有之一
当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概 念,可能真解释不清楚.有句话这么说:如果你不能向一个6岁小孩解 ...
- 转:JavaScript中的this陷阱的最全收集
在其他地方看到的,觉得解释的狠详细,特此分享 当有人问起你JavaScript有什么特点的时候,你可能立马就想到了单线程.事件驱动.面向对象等一堆词语,但是如果真的让你解释一下这些概念,可能真解释不清 ...
- JavaScript中常用的正则表达式日常整理(全)
//校验是否全由数字组成 ? 1 2 3 4 5 6 function isDigit(s) { var patrn=/^[0-9]{1,20}$/; if (!patrn.exec(s)) retu ...
- JavaScript中“&&”和“||”操作符的意义,深入理解和使用场景
一.概念 与其他语言不同,在js中,逻辑运算符可以返回任何类型的数据,不仅仅是true和false. &&和||的返回值是两个操作数的其中一个.即a&&b或者a||b ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...
- JavaScript中的this陷阱的最全收集
JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值.事实并非如此,在JavaScript中,最 ...
- javascript中的this在不同场景下的区别
javascript在初版的设计上存在失误,导致了这门语言在使用时,经验型写法并不能得到像其它几个流行语言一样预期.其中的this的使用就是一个典型. this在javascript中是由解释器注入的 ...
- JavaScript 中的数据类型
Javascript中的数据类型有以下几种情况: 基本类型:string,number,boolean 特殊类型:undefined,null 引用类型:Object,Function,Date,Ar ...
随机推荐
- what a malloc has to do
1) Allocate a chunk of memory big enough to satisfy the request, and return a pointer to it.2) Remem ...
- python3.5 + django1.9.1+mysql
python3 对mysql 的驱动不再是mysqldb 具体步骤 : 1 安装依赖 pip install PyMySQL 2 修改配置 __init__.py import pymysql pym ...
- 调试minix内核
调试的时候,要把电脑当作单片机来使用,故先需要添加串口,方便进行打印调试 http://wiki.minix3.org/doku.php?id=developersguide:serialout 1. ...
- KMP算法中的next数组求解示意图
- ASP.NET页面生命周期描述
下面是ASP.NET页面初始的过程:1. Page_Init();2. Load ViewState;3. Load Postback data;4. Page_Load();5. Handle co ...
- PHP详解$_SEVER常用变量
$_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言 $_SERVER['HTTP_ACCEPT'] //当前请求的Accept头部的内容,例如text/html,appli ...
- codeforces DIV2 D 最短路
http://codeforces.com/contest/716/problem/D 题目大意:给你一些边,有权值,权值为0的表示目前该边不存在,但是可以把0修改成另外一个权值.现在,我们重新建路, ...
- libevent在windows下使用步骤详解
一 环境 官方下载地址:http://libevent.org/版本:libevent-2.0.22-stable 二 编译静态库 1 解压把上面下载到libevent-2.0.22-stable.t ...
- js冒泡事件小解
何为冒泡事件?简单来说事件就像一个水里的泡泡,先触发当前对象再触发其父元素,然后是父元素的父元素... eg: <div class="out" onclick= " ...
- C++虚函数的新用法
1.今天在segmentfault上看到了一个C++虚函数的新用法,先上代码 #include <iostream> using namespace std; class B { publ ...