对js中this的一点点理解
1 当函数作为对象的方法被调用的时候 this就指向该对象
var o = {
prop: 37,
f: function() {
return this.prop;
}
}; console.log(o.f()); // logs 37
上面的例子中,当 o.f()
被调用时,函数内的this将绑定到o对象。
在何处或者如何定义调用函数完全不会影响到this的行为。在上一个例子中,我们在定义o的时候为其成员f定义了一个匿名函数。但是,我们也可以首先定义函数然后再将其附属到o.f
。这样做this的行为也一致:
var o = {prop: 37}; function independent() {
return this.prop;
} o.f = independent; console.log(o.f()); // logs 37
这说明this的值只与函数 f 作为 o 的成员被调用有关系。
类似的,this 的绑定只受最靠近的成员引用的影响。在下面的这个例子中,我们把一个方法g当作对象o.b
的函数调用。在这次执行期间,函数中的this将指向o.b
。事实上,这与对象本身的成员没有多大关系,最靠近的引用才是最重要的。
o.b = {
g: independent,
prop: 42
};
console.log(o.b.g()); // logs 42
2 作为普通函数调用的时候 thi指向全局对象window
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="div1"></div>
<script>
window.id = 'window';
document.getElementById('div1').onclick = function () {
console.log(this.id); //div1
var cb = function () {
console.log(this.id);
};
cb(); //window
}
</script>
</body>
</html>
上述代码中的document.getElementById('div1')返回一个dom元素对象,所以该点击监听事件作为该对象的方法调用,this指向id为div1的dom元素对象,this.id为div1;
而点击事件中的函数cb是普通函数,所以this指向window,this.id为window。
3 在严格模式下this不会指向全局对象,而是undefined , 如下:
function func () {
'use strict';
console.log(this === undefined);
}
func(); // true
4 丢失的this
var obj = {
name: 'peak',
getName: function () {
return this.name;
}
};
console.log(obj.getName()); // peak
var getNm = obj.getName;
console.log(getNm()); // undefined
5 构造函数中的this
如果函数和new关键字一起使用,则这个函数称为构造函数。在函数内部,this会指向新创建的对象。
function Foo(){
this.name = "foo";
}
Foo.prototype.sayHello = function(){
console.log('hello,'+this.name)
}; var foo = new Foo();
foo.sayHello; // hello,fo
上述代码中this则指向新创建的对象foo
注意:构造器可以手动设置返回其他的对象,如果返回值不是一个对象,则返回this,否者,返回该对象。
function C2(){
this.a = 37;
return {a:38};
} o = new C2();
console.log(o.a); /
6 使用apply、call显示的设置this
function foo(a, b, c) {}
var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将作为函数的参数被接收,如下所示
foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3
当使用 Function.prototype
上的 call
或者 apply
方法时,函数内的 this
将会被 显式设置为函数调用的第一个参数。
因此函数调用的规则在上例中已经不适用了,在foo
函数内 this
被设置成了 bar。
使用 call
和 apply 函数的时候要注意,
如果传递的 this 值不是一个对象,JavaScript 将会尝试使用内部 ToObject 操作将其转换为对象。因此,如果传递的值是一个原始值比如 7
或 'foo'
,那么就会使用相关构造函数将它转换为对象,所以原始值 7
通过new Number(7)
被转换为对象,而字符串'foo'使用 new String('foo')
转化为对象,例如:
function bar() {
console.log(Object.prototype.toString.call(this));
} bar.call(7); // [object Number]
7 bind 方法
ECMAScript 5 引入了Function.prototype.bind。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。
function f(){
return this.a;
} var g = f.bind({a:"azerty"});
console.log(g()); // azerty var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty
注意: 在对象的字面声明语法中,this
不能用来指向对象本身。 因此 var obj = {me: this}
中的 me
不会指向 obj
,因为 this
只可能出现在上述的五种情况中。 这个例子中,如果是在浏览器中运行,obj.me
等于 window
对象。
对js中this的一点点理解的更多相关文章
- js中的回调函数的理解和使用方法
js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...
- js中的闭包之我理解
闭包是一个比较抽象的概念,尤其是对js新手来说.书上的解释实在是比较晦涩,对我来说也是一样. 但是他也是js能力提升中无法绕过的一环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的 ...
- JS 中 call 和 apply 的理解和使用
本文受到了知乎问题 如何理解和熟练运用js中的call及apply? 的启发. obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1 ...
- js中prototype,constructor的理解
连看4篇前辈的文章,记录一些知识点 Javascript继承机制的设计思想 Javascript 面向对象编程(一):封装 Javascript面向对象编程(二):构造函数的继承 Javascript ...
- js中的回调函数的理解
一,常见的但是不是特别注意的回调方法. 1.1,ajax $.ajax({ url:"test.json", type: "GET", data: {usern ...
- js中对同步和异步的理解
你应该知道,javascript语言是一门“单线程”的语言,不像java语言,类继承Thread再来个thread.start就可以开辟一个线程,所以,javascript就像一条流水线,仅仅是一条流 ...
- 关于JS中apply方法的基本理解
最近研究OpenLayers源码时,发现其中使用了比较多的apply方法,对其也是很不明白.于是上网经过多方面了解以及自己细细体会后,终于算是基本明白是其干什么的了,这里分享下.apply方法的造型是 ...
- JS中面向对象的,对象理解、构造函数、原型、原型链
6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属 ...
- js中立即执行函数写法理解
在理解了一些函数基本概念后,回头看看( function(){…} )()和( function (){…} () )这两种立即执行函数的写法,最初我以为是一个括号包裹匿名函数, 并后面加个括号立即调 ...
随机推荐
- CPU占用率呈正弦实现,及实时输出进程和线程的CPU占用率
CPU占用率呈正弦实现,及实时输出进程和线程的CPU占用率 #include "stdafx.h" #include <windows.h> #include < ...
- MongoDB 搭建分片集群
在MongoDB(版本 3.2.9)中,分片是指将collection分散存储到不同的Server中,每个Server只存储collection的一部分,服务分片的所有服务器组成分片集群.分片集群(S ...
- 页面loading效果
当网页太大,打开太慢的时候,为了增加良好的用户体验(不让用户眼巴巴的等,心中暗骂c,这么慢),我们需要加一个等待动画. 只需把以下代码加入页面中即可,图片可以根据自己的需求更换,更换图片之后需要改变l ...
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
需要下载Genymotion-ARM-Translation_v1.1.zip ARM插件包 用于安装ARM架构的程序,将下载好的zip包用鼠标拖到虚拟机窗口中,出现确认对跨框点OK就行.然后重启你 ...
- 【原生态】Http请求数据 与 发送数据
今天项目组小弟居然问我怎么用java访问特定的地址获取数据和发送请求 Http请求都是通过输入输出流来进行操作的,首先要制定GET或者POST,默认是GET,在安全和数据量较大情况下请使用post 根 ...
- MySQL Range Optimization
8.2.1.3 Range Optimization MYSQL的Range Optimization的目的还是尽可能的使用索引 The range access method uses a sing ...
- 如何用Perl对Excel的数据进行提取并分析
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了一个表的数据量统计日报,主要是针对数据库中使用较频繁,数据量又较大的31张表.该日报有两个sheet组成,第一个sheet是数据填写,第二个sh ...
- Lua 学习笔记(十一)元表与元方法
在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...
- JavaScript框架设计(四) 字符串选择器(选择器模块结束)
JavaScript框架设计(四) 字符串选择器(选择器模块结束) 经过前面JavaScript框架设计(三) push兼容性和选择器上下文的铺垫,实现了在某一元素下寻找,现在终于进入了字符串选择器 ...
- C# 在excel表格中检索并导出数据
由于工作需要,我经常使用excel文档来存储和处理各种数据,在生活中偶尔也会使用excel表格来记录各种开销,相信很多朋友也和我一样.Excel的功能很强大,其中一个很实用的数据处理功能就是查找和替换 ...