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 ...
随机推荐
- servlet第2讲(下集)----创建servlet实例(继承HttpServlet)
- SSH登录很慢问题的解决方法
用ssh连其他linux机器,会等待10-30秒才有提示输入密码.严重影响工作效率. 关闭ssh的gssapi认证 用ssh -v user@server 可以看到登录时有如下信息: debug1: ...
- Linux入门学习教程:虚拟机体验之KVM篇
本文中可以学习到的命令: 1. aptitude 是apt-get 不会产生垃圾的版本 2. dpkg -L virtualbox 显示属于该包的文件 lsmod | grep kvmfi ...
- Linux查看CPU和内存使用情况 【转】
Linux查看CPU和内存使用情况 在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 ...
- input text中不能显示空格后的内容
<input type="text" value='' /> 即value=后面一定要用引号引起来,不然就会出现空格及其后内容不显示的问题
- 校验 MD5 值
Linux 环境下:打开终端,输入命令:"md5sum filename",将结果与网页提供值对比.Windows 环境下:下载 MD5 校验软件并使用.
- Qt Quick里的图形效果:阴影(Drop Shadow)
Qt Quick提供了两种阴影效果: DropShow,阴影.这个元素会根据源图像,产生一个彩色的.模糊的新图像,把这个新图像放在源图像后面,给人一种源图像从背景上凸出来的效果. InnerShado ...
- Photoshop基础,前景背景,图层,选取
1*前景色背景色 Alt+Delete 键 前景色填充 Ctrl+Delete 键 背景色填充 X 颜色转换 D 颜色互换 两个填充的原因: 2*图层(只要做东西就要建图层)透明的纸进行叠加,尽量多建 ...
- sudo su– user
[root@localhost ~] # visudo –f /etc/sudoers 在文件中的root账户下添加需要切换root账户的账户 root ALL=(ALL) ALL user ALL= ...
- Spring Boot 系列教程3-MyBatis
MyBatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache 迁移到了google code,并且改名为MyBatis .2013年11月迁移到Git ...