对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 (){…} () )这两种立即执行函数的写法,最初我以为是一个括号包裹匿名函数, 并后面加个括号立即调 ...
随机推荐
- Atitit 数据库的事件机制--触发器与定时任务attilax总结
Atitit 数据库的事件机制--触发器与定时任务attilax总结 1.1. 事件机制的图谱1 2. 触发器的类型2 3. 实现原理 After触发器 Vs Instead Of触发器2 3.1. ...
- Atitit 查询优化器的流程attilax总结
Atitit 查询优化器的流程attilax总结 1.1. 来理解该过程:1 1.2. 关于这些优化器的最重要原则的就是:尽可能的减少扫描范围,2 1.3. .筛选条件分析2 1.4. 二.索引优化2 ...
- Oracle 创建普通用户,并赋予权限
采用sys or system / manager as sysdba; 连接数据库. 创建普通用户konglin: create user konglin identified by pwd_ora ...
- Hibernate增删查改语句
我用的数据库是MySQL,实体类叫Product create table Product ( proId integer not null auto_increment, proName varch ...
- 【原创】开源.NET排列组合组件KwCombinatorics使用(三)——笛卡尔积组合
本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...
- MVC实用架构设计(三)——EF-Code First(5):二级缓存
前言 今天我们来谈谈EF的缓存问题. 缓存对于一个系统来说至关重要,但是是EF到版本6了仍然没有见到有支持查询结果缓存机制的迹象.EF4开始会把查询语句编译成存储过程缓存在Sql Server中,据说 ...
- Android数据存储之Sqlite的介绍及使用
前言: 本来没有打算整理有关Sqlite数据库文章的,最近一直在研究ContentProvider的使用,所有觉得还是先对Sqlite进行一个简单的回顾,也方便研究学习ContentProvider. ...
- 程序员眼中的 SQL Server-非聚集索引能给我们带来什么?
写在前面 最近在做的一个项目,页面访问的时候很慢(大概几秒钟的样子),然后用日志记录的方式,来排查这个问题,最后发现是 Entity Framework 初始化的一个坑(大概要花 6-7 秒),详见: ...
- 使用yield进行异步流程控制
现状 目前我们对异步回调的解决方案有这么几种:回调,deferred/promise和事件触发.回调的方式自不必说,需要硬编码调用,而且有可能会出现复杂的嵌套关系,造成"回调黑洞" ...
- DG环境数据库RMAN备份策略制定
DG环境数据库RMAN备份策略制定: 主库(Primary) 全库备份 归档备份 删除历史文件夹 备库(Standby) 删除归档 引用说明 主库(Primary) $ crontab -l 0 1 ...