这篇文章主要介绍了javascript中this属性,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
this总是返回一个对象,即返回属性或方法当前所在的对象。
对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this的指向是可变的。
eg:
var A = { name : '张三', describe : function(){ return '姓名:' + this.name; } }; var B = { name : '李四' } B.describe = A.describe; B.describe();
结果:“姓名:李四”
再看一个例子:
var A = { name : '张三', describe : function(){ return '姓名:' + this.name; } }; var name = '李四' f = A.describe; f();
结果也是“姓名:李四”,因为这时this指向f运行时所在的对象——顶层window
this的使用场合
1、全局环境——无论this是不是在函数内部,只要是在全局环境下运行,this就是指顶层对象window
2、构造函数——指的是实例对象
eg:
var Obj = function(p){ this.p = p; } Obj.prototype.a = function(){ return this.p; } var obj = new Obj('color'); obj.a(); obj.p;
结果是都返回"color"
上面代码定义了一个构造函数Obj,由于this指向实例对象,所以在Obj中定义this.p,相当于定义实例对象有一个p属性,然后m方法可以返回这个p属性。
3、对象的方法
var obj = { foo : function(){ console.log(this); } }; obj.foo();//obj
只有直接在obj对象上调用foo方法,this才会指向obj,其他用法时,this都指向代码块当前所在的对象。
情况一:(obj.foo = obj.foo)()——window
情况二:(false || obj.foo)()——window
情况三:(1 , obj.foo)()——window
上述代码中,obj.foo先运算再执行,即使它的值没有变化,this也不再指向obj了
4、Node
在Node中,若在全局环境里,this指向global,模块环境中,this指向module.exports
this使用注意点
1、避免多层this
var o = { f1 : function(){ console.log(this); var f2 = function(){ console.log(this); }(); } } o.f1();
执行结果是:
{f1: ƒ}
Window {decodeURIComponent: ƒ, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
为什么f2中的this指向的是全局对象呢?因为上面那段代码的执行过程实际上是
var temp = function(){ console.log(this); }; var o = { f1 : function(){ console.log(this); var f2 = temp(); } } o.f1();
解决方法一——在第二层改用一个指向外层this的变量
var o = { f1 : function(){ console.log(this); var that = this; var f2 = function(){ console.log(that); }(); } } o.f1();
使用一个变量固定this的值,然后内层调用这个变量,是非常有用而且大量应用的方法
解决方法二——使用严格模式,在严格模式下,如果函数内部的this指向顶层对象就会报错。
2、避免数组处理方法中使用this
var o = { v : 'hello', p : ['a1','a2'], f : function(){ this.p.forEach(function(item){ console.log(this.v + ' ' + item); }); } } o.f();
结果:
undefined a1
undefined a2
导致这个结果的原因跟上一段的多层this是一样的
解决方法一——使用中间变量
var o = { v : 'hello', p : ['a1','a2'], f : function(){ var that = this; this.p.forEach(function(item){ console.log(that.v + ' ' + item); }); } } o.f();
解决方法二——将this当作forEach方法的第二个参数,固定它的运行环境
var o = { v : 'hello', p : ['a1','a2'], f : function(){ this.p.forEach(function(item){ console.log(this.v + ' ' + item); },this); } } o.f();
3、避免回调函数中的this
var o = new Object(); o.f = function(){ console.log(this === o); } o.f();//true $("#button").on("click",o.f);//false
绑定this的方法
JavaScript提供了call、apply、bind三个方法来切换/固定this的指向
function.prototype.call()
函数实例的call方法可以指定函数执行时this所在的作用域,call方法的参数量个对象,如果参数为空、null、undefined,则默认传入全局对象。如果call的参数不是对象,那么会被自动包装成包装对象。func.call(thisValue,arg1,arg2,……)
var n = 123; var obj = {n : 456}; function a(){ console.log(this.n); } a.call();//123 a.call(null);//123 a.call(undefined);//123 a.call(window);//123 a.call(obj);//456
call方法的一个应用是调用对象的原生方法
var obj = {}; //原生方法 obj.hasOwnProperty('toString');//false //覆盖了原生的方法 obj.hasOwnProperty = function(){ return true; } obj.hasOwnProperty('toString');//true //调回原生的方法 Object.prototype.hasOwnProperty.call(obj,'toString');//false
function.prototype.apply()
apply与call唯一的区别是apply接受一个数组作为函数执行时的参数,func.apply(thisValue,[arg1,arg2,……])
apply的应用之一——找出数组的最大元素
var a = [10,3,4,2]; Math.max.apply(null,a);
apply的应用之二——将数组的空元素变为undefined(因为数组的forEach方法会跳过空元素,却不会跳过undefined)?
var a = ['a','','b']; function print(i){ console.log(i); } a.forEach(print);//a b Array.apply(null,a).forEach(print);//a undefined b
运行结果跟上面不太一样,都是a b
apply的应用之三——转换类似数组的对象
Array.prototype.slice.apply({0:1,length:1});
apply的应用之四——绑定回调函数的对象
var o = new Object(); o.f = function(){ console.log(this === o); } var f = function(){ o.f.apply(o);//或o.f.call(o); } $("#button").on("click",f);
function.prototype.bind()
bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数
下面的例子在将方法赋值后会出错
var d = new Date(); d.getTime(); var print = d.getTime; print();//Uncaught TypeError: this is not a Date object.
解决方法:
var print = d.getTime.bind(d);
bind比call和apply更进一步的是,除了绑定this以外,还可以绑定原函数的参数
var add = function(x,y){ return x * this.m + y * this.n; } var obj = { m:2, n:2 } var newAdd = add.bind(obj,5);//绑定add的第一个参数x newAdd(5);//第二个参数y
对于那些不支持bind方法的老式浏览器,可以自行定义bind方法
if(!('bind' in Function.prototype)){ Function.prototype.bind = function(){ var fn = this; var context = arguments[0]; var args = Array.prototype.slice.call(arguments,1); return function(){ return fn.apply(context,args); } } }
以上是详解javascript中this属性的详细内容。更多信息请关注PHP中文网其他相关文章!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Dreamweaver CS6
视觉化网页开发工具

记事本++7.3.1
好用且免费的代码编辑器

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境