javascript this可以绑定到:全局对象,自己定义的对象,用构造函数生成的对象,通过call或者apply更改绑定的对象

   1.全局对象 

1
2
3
4
5
function globalTest(name){
     this.name=name;
 }
 globalTest('tree');
 console.log(name);//tree,默认生成了全局属性name,并给name属性赋值了,这种写法一般是不允许的

  

2.自己定义的对象

var subway={
name:'1号线',
speed:0,
run:function(speed){
this.speed=speed;
}
};
subway.run(100);
console.log(subway.speed); //100,this绑定到对象subway

3.用构造函数生成的对象

构造函数约定第一个字母要大写,只有用new调用的时候才算构造函数,否则跟普通函数没有什么不同,用new调用构造函数,this会绑定到生成的对象。

function Subway(speed){
this.speed=speed;
}
var s=new Subway(100);
console.log(s.speed);//100;this绑定到新生成的对象

   4.指定的对象,通过call或者apply绑定

call函数和apply函数的区别是参数不一样,两个方法都可以改变this绑定的对象,如下

call(obj,param1,param2……);

apply(obj,[]/*params[]参数数组*/);

function Subway(name){
this.name=name;
this.speed=0;
this.run=function(speed){
this.speed=speed;
};
}
var s=new Subway('1号线');
s.run(300);
console.log('一号线速度为:',s.speed);//300;this绑定到新生成的对象s
var s1=new Subway('2号线');
s.run.apply(s1,[100]);
console.log('二号线速度为:',s1.speed);//100;this绑定到对象s1
s.run.call(s1,200);
console.log('二号线速度为:',s1.speed);//200;this绑定到对象s1

最后:

javascript有一个设计缺陷,使得的this绑定混乱

var subway={
name:'1号线',
speed:0,
run:function(speed){
this.speed=speed; //绑定到对象本身
function test(speed){
this.speed=speed+50;//竟然绑定到全局变量了,真是匪夷所思啊
}
test(speed);
}
};
subway.run(100);
console.log(subway.speed);//100
console.log(speed);//150

解决方法约定用that代替this

var subway={
name:'1号线',
speed:0,
run:function(speed){
var that=this; //用that代替this
this.speed=speed;
function test(speed){
that.speed=speed+50;
}
test(speed);
}
};
subway.run(100);
console.log(subway.speed);//150 -----------------------------------------------------------------

var a=1;
function s(){
     var a=2;
     alert(a);
  }

function s1(){
    a=3;
    alert(a);
}

function s2(){
    var a=4;
    alert(this.a);
}

function s3(){
    a=5;
    alert(this.a);
}

s();//2
s1();//3
s2();//undefined
s3();//5


随机推荐

  1. jQuery 实时监听<input>输入值的变化

    这方法比 on('keydown') 更实时 <input type='text' id='input1'/>$(document).ready(function(){ $('#input ...

  2. iOS10新特性

    1.Siri API 的开放自然是 iOS 10 SDK 中最激动人心也是亮眼的特性.Apple 加入了一套全新的框架 Intents.framework 来表示 Siri 获取并解析的结果. 在 i ...

  3. MYSQL提权总结

    最近在测试一个项目,遇到了MYSQL数据库,想尽办法提权,最终都没有成功,很是郁闷,可能是自己很久没有研究过提权导致的吧,总结一下MYSQL提权的各种姿势吧,权当复习了.关于mysql提权的方法也就那 ...

  4. js的forEach,for in , for of

    forEach遍历数组 [].forEach(function(value, index, array) { // ... }); 例子 var myArry =[1,2,3,4]; myArry.d ...

  5. QT 调用VS2015编写的Dll

    最近在用QT调用VC生成的库,QT使用的是MinGW调试器,出现与动态库不兼容的问题,最后发现QT只能识别VC生成的C格式下的动态库 也就是在导入导出设置时加入extern "C" ...

  6. Linux CentOS 中安装 MySql

    CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1. 下载mysql的repo源 $ wget http://repo.mysql.com ...

  7. Appium环境搭建

    早就想学习移动端的自动化测试:今天看了些资料@虫师,整理下环境搭建流程:标"1"为最佳流程: 文字版的流程可以参见虫师的博客:

  8. 用SQL命令查看Mysql数据库大小

    要想知道每个数据库的大小的话,步骤如下: 1.进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; 2.查询所有数据的大小: s ...

  9. NET基础(4):引用类型和值类型

    CLR支持两种类型:引用类型和值类型.虽然FCL的大多数类型都是引用类型,但程序员用的最多的还是引用类型,引用类型总是从托管堆分配,c#的new操作符返回对象内存地址-即指向对象数据的内存地址.使用引 ...

  10. 设置更新源和下载ferret

    kali无法定位软件包 解决: deb http://http.kali.org/kali kali-rolling main non-free contrib kali可用的官方更新源(cd /et ...