this的用法

this在日常javascript编码中很常见, 但是一直以来没有好好总结过。 今天在这里好好总结一下。 本文只讨论浏览器环境。

this指向全局

var name = "window";
function foo() {
var name = "local";
console.log(this.name);
}
foo();

相信这段代码大家都看到过,在这里this指向了全局,输入结果是"window".一开始我也不理解为什么有些时候this是指向内部函数,有些时候是指向window了。 相信好多小伙伴都和我一样比较疑惑, 后来我去翻阅犀牛书,犀牛书对函数this的解释是:关键字this没有作业域限制, 嵌套的函数不会从调用它的函数中继承this如果函数嵌套作为方法调用其this的值指向调用它的对象。 如果嵌套函数作为函数调用,其this不是全局对象(非严格模式下)就是undefined(严格模式下)。

其实总结一下这段话就是: 一个函数如果是执行而不是作为一个对象的方法来使用,

那么它就指向全局对象或者undefined。 所以这就解释了第一段代码。

那接下来我们解释第二个结论:

作为对象的方法使用。

var name = "window";
function foo() {
var name = "local";
console.log(this.name);
}
var obj = {
name: 'local',
foo: foo
};
obj.foo();

根据上面的结果, 我们很容易得出这里的this就指向了对象obj。在一些称谓中,这个叫做this的隐式绑定。

call,apply 对this的显式绑定

个人不喜欢文字堆砌,还是直接上代码吧。

var name = "window";
var obj = {
name: "obj"
};
function foo() {
console.log(this.name);
}
foo(); //直接调用函数 this指向window
foo.call(obj); //改变函数的上下文,把obj传进去

这里显式绑定了函数的上下文,让this指向了obj,结果输入为“obj”

顺带提一下,call,apply的区别,面试题经常被问。

使用call或者apply让一个函数以一个对象的方法执行,第一个参数是指定上下文,可以是一个对象也可以是null。

call和apply区别是第二个参数,apply是数组的形式传参。

this在构造函数的使用

this的构造函数中使用蛮多的,也蛮方便的。

function Foo() {
this.a = "foo";
}
var f = new Foo();
console.log(f.a);

通过new一个函数,那么在构造函数中,this指向实例化的对象f。

上面说完了理论知识,那么我们来几个应用场景题

example 1:
var name = "window";
function foo() {
console.log(this.name);
}
var obj = {
name: 'obj',
foo: foo
};
var a = obj.foo;
a();
obj.foo = null;
a();

可能有些同学会认为function也是对象,对象的复制是引用类型复制,那么只是指向obj.foo,如果obj.foo置空了,那么a也就不能输出this.name了。其实结果不是的,函数的复制是值的复制,和数组复制造成引用或者其他的引用不一样。简单点说

a = obj.foo = function {
console.log(this.name);
}

那么,现在执行a(); 和obj里面的foo函数还没有任何关系了。既两次执行结果都是'window';

example 2:

看完上面这个例子,同样的我们有些是经常使用回调函数,把函数当一个参数传递,那这个参数是不是也是值的复制?请看下面的例子。

function aaa(fn) {
fn();
} function foo() {
console.log(this.name);
} var obj = {
name: 'obj',
foo: foo
}; aaa(obj.foo);

如果看不懂这个的话 ,这里也可以简化一下

function aaa(fn) { //在参数这里 可以理解为 var fn = obj.foo;
fn();
}

从例子1中我们可以知道函数是值的复制,那必然在aaa里面执行另外一个函数,而不是执行一个函数的方法,结果仍然是'window'.

example 3:
var name = "window";
setTimeout(function(){
var name = "local";
console.log(this.name);
},1000);

相信大家经常用定时器吧,那么有没有踩过这个坑,在定时器中,this是指向全局window的。

因为setTimeout是window下面的方法。代码可以转换为:

var name = "window";
window.setTimeout(function(){
var name = "local";
console.log(this.name);
},1000);

一个对象的方法使用,那内部的this是指向这个方法,必然this指向了这个对象本身,既window。

参考文档:

javascript权威指南第六版

晓婼:http://www.cnblogs.com/xiaoruo/p/4492453.html

浅析js中的this的更多相关文章

  1. 浅析JS中的模块规范(CommonJS,AMD,CMD)////////////////////////zzzzzz

    浅析JS中的模块规范(CommonJS,AMD,CMD)   如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已.     ...

  2. 浅析JS中的堆内存与栈内存

    最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...

  3. 浅析 JS 中的作用域链

    作用域链的形成 在 JS 中每个函数都有自己的执行环境,而每个执行环境都有一个与之对应的变量对象.例如: var a = 2 function fn () { var a = 1 console.lo ...

  4. 浅析JS中的模块规范(CommonJS,AMD,CMD)

    如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已. 现在就看看吧,这些规范到底是啥东西,干嘛的. 一.CommonJS ...

  5. 浅析js中2个等号与3个等号的区别(转)

    首先,== equality 等同,=== identity 恒等. ==, 两边值类型不同的时候,要先进行类型转换,再比较. ===,不做类型转换,类型不同的一定不等. 下面分别说明: 先说 === ...

  6. 浅析JS中的模块规范AMD和CMD

    一.AMD AMD就只有一个接口:define(id?,dependencies?,factory); 它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样: d ...

  7. 浅析js中的堆和栈

    这里先说两个概念:1.堆(heap)2.栈(stack)堆 是堆内存的简称.栈 是栈内存的简称.说到堆栈,我们讲的就是内存的使用和分配了,没有寄存器的事,也没有硬盘的事.各种语言在处理堆栈的原理上都大 ...

  8. 浅析js中取绝对值的2种方法

    1.abs()   var aaa=-20;   var bbb=Math.abs(aaa); 2.加减法   var aaa=-20;   var bbb=-aaa

  9. JS中的 map, filter, some, every, forEach, for in, for of 用法总结和区别

    JS中的 map, filter, some, every, forEach, for in, for of 用法总结和区别  :https://blog.csdn.net/hyupeng1006/a ...

随机推荐

  1. wikioi 3038 3n+1问题

    题目描述 Description 3n+1问题是一个简单有趣而又没有解决的数学问题.这个问题是由L. Collatz在1937年提出的.克拉兹问题(Collatz problem)也被叫做hailst ...

  2. PL/pgSQL学习笔记之十

    http://www.postgresql.org/docs/9.1/static/plpgsql-declarations.html 39.3.3. 类型拷贝 variable%TYPE %TYPE ...

  3. 有关于CSS的面试题和练习

    如果你处在一个需要面试别人有关于CSS方面技巧和知识,一时想起来还真有点难.我把我能想出来的整理在一起,提供给大家参考. 练习要做 正如他们说的,大家实际工作很重要.当然,大家通过工作练习更为重要.这 ...

  4. SpringAOP 基础具体解释

    Spring AOP对于刚開始学习spring的同学来说有点难以理解.我刚工作的时候都没怎么理解,如今略微理解了一点,所以在这里我将用嘴简单的样例,最通俗易懂的话语来说出我的理解,可能因为我对Spri ...

  5. SGU 532. Building Foundation 暴力

    532. Building Foundation 题目连接: http://acm.sgu.ru/problem.php?contest=0&problem=532 Description A ...

  6. 如何从iTunes Connect中提款呢?

    最近在AppStore有点小小小收入,但如何从iTunes Connect中提款呢? (Payments and Financial Reports) 网上查了下,发现有种说法:“只要账号余额达到15 ...

  7. 【JavaScript】JS的启动机制

    DOM  Event------------------>触发function() function  自身的调用 主要就是调用function 1.DOM Event 2.调用function

  8. UIButton设置了UIControlStateSelected和UIControlStateHighlighted状态的图片点击会闪烁的解决方案

    [btn setBackgroundImage:img1 forState:UIControlStateSelected|UIControlStateHighlighted]; [btn setIma ...

  9. Linux 的启动流程

    转载:http://www.ruanyifeng.com/blog/2013/08/linux_boot_process.html 更多文档参见:http://pan.baidu.com/s/1hqo ...

  10. C#透明窗体代码详解

    using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServi ...