javascript学习笔记(10)--this

在一个对象中绑定函数,称为这个对象的方法
在JavaScript中,对象的定义是这样的

 var xiaoming = { name: '小明', birth: 2000 };

但是,如果我们给xiaoming绑定一个函数,就可以做更多的事情
比如,写个age()方法,返回xiaoming的年龄

var xiaoming = { 
name: '小明',
 birth:2000,
age: function () 
{
 var y = new Date().getFullYear()- this.birth;
  return y ;
   } 
   };
xiaoming.age; // function xiaoming.age()
 xiaoming.age(); //20

绑定到对象上的函数称为方法,和普通函数也没啥区别,这个我们也在上一节提到过了,当然是避免和其他的全局变量冲突,所以没有定义到window,定义到了xiaoming上

但是它在内部使用了一个this关键字,这个this也是javascript内比较重要的概念

在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是xiaoming这个变量
所以,this.birth可以拿到xiaoming的birth属性

function getAge() {
 var y = new Date().getFullYear()- this.birth; return y ; }
var xiaoming = { name: '小明', birth: 2000, age: getAge };
xiaoming.age;//function getAge()
xiaoming.age();//20
getAge();//NaN

调用xiaoming的方式没问题,但是单独调用函数getAge()却返回NaN,这就涉及到了this的指向

this的指向视情况而定,如果以对象的方法形式调用,比如xiaoming.age(),该函数的this指向被调用的对象,也就是xiaoming
如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window
如果这么写

var fn = xiaoming.age;// // 先拿到xiaoming的age函数
fn();//NaN

也是不行的
要保证this指向正确,必须用obj.xxx()的形式调用

在strict模式下函数的this指向undefined

 'use strict';
  var xiaoming = 
  {
   name: '小明', 
   birth: 2020, 
   age: function ()
    { return new Date().getFullYear() - this.birth; } };
    var fn = xiaoming.age
     fn();//TypeError: Cannot read property 'birth' of undefined

修改一下

 'use strict'; 
 var xiaoming = { 
 name: '小明',
  birth: 1990,
   age: function () {
    function getAgeFromBirth()
     { return  new Date().getFullYear() - this.birth; }
   return getAgeFromBirth(); } };
   xiaoming.age();
   TypeError: Cannot read property 'birth' of undefined

又报错了,原因是this指针只在age方法的函数内指向xiaoming,在函数内部定义的函数,this又指向undefined了(在非strict模式下,它重新指向全局对象window)
所以this只有在对象的方法函数里才指向对象,方法函数里的函数都指向window(strcit下undefiend)

那我们如何修复呢
我们用一个that变量首先捕获this

 'use strict'; 
var xiaoming = { 
 name: '小明',
  birth: 2000, 
  age: function () 
  { var that = this; 
   function getAgeFromBirth() { return  new Date().getFullYear() - that.birth; }
   return getAgeFromBirth(); } };
xiaoming.age();//20

在xiaoming的方法函数里首先就把this用that捕获了,然后在方法函数里定义的函数如果需要指向对象就用that即可

apply
虽然在一个独立的函数调用中,根据是否是strict模式,this指向undefined或window,不过,我们还是可以控制this的指向

要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变
量,第二个参数是Array,表示函数本身要传入的参数
用apply修复getAge()调用

function getAge()
{ return new Date().getFullYear() - this.birth; }
var xiaoming = { 
name: '小明', 
birth: 2000,
 age: getAge };
 xiaoming.age(); //20这个毫无疑问是对的
 getAge.apply(xiaoming, []); 
 getAge.apply(xiaoming);//20

两种写法都可以,只需要传入xiaoming作为绑定的this对象,因为这个函数无参

另一个与apply()类似的方法是call(),唯一区别是
apply()把参数打包成Array再传入
call()把参数按顺序传入
通过具体例子看看吧

Math.max.apply(null, [3, 5, 4]); // 5 
Math.max.call(null, 3, 5, 4); // 5 
getAge.call(xiaoming);//20

对普通函数调用,我们通常把this绑定为null

利用apply(),我们还可以动态改变函数的行为
JavaScript的所有对象都是动态的,即使内置的函数,我们也可以重新指向新的函数
现在假定我们想统计一下代码一共调用了多少次parseInt()
最佳方案是用我们自己的函数替换掉默认的parseInt()

var count = 0;
 var oldParseInt = parseInt;//保存我们的parseInt
 parseInt=function(){
 count+=1;
 return oldParseInt.apply(null,arguments);}
 parseInt('1')
1
parseInt('2')
2
parseInt('1312')
1312
parseInt('5634')
5634
count
4

其实this挺复杂的…最开始第一遍我也没太理解
也就是现在模模糊糊的理解了
strict模式下,一般的this指向undefined,而非strict模式下,this指向window
只有在什么情况下this会指向对象呢,就是在对象的方法函数内,而且就只限于方法函数,方法函数的内部函数this也指向undefined

那为什么需要this呢
你可能也觉得很麻烦,确实,时不时要考虑这个this绑定的是不是我们需要的对象,这很繁琐
直接把this指明成xiaoming,什么事情也没有

var xiaoming = { 
 name: '小明',
  birth: 2000, 
  age: function () 
  { 
   function getAgeFromBirth() { return  new Date().getFullYear() - xiaoming.birth; }
   return getAgeFromBirth(); } };
   xiaoming.age();//20
var getAge=function(){return new Date().getFullYear() -xiaoming.birth;}
var xiaoming = { 
 name: '小明',
  birth: 2000, 
  age: getAge}
xiaoming.age();//20

这样确实可以解决问题,但是这样带来的坏处就是不灵活
javascript是面向对象编程,特别是之后开发的时候,可能这个函数需要适用到需要变量上,这样写明显是不灵活的
但如果我们添加了this这个概念,只需要在使用每个函数修改一下指向,这样不大大提升了整体代码的灵活度吗,而且也可以防止我们写串了,这样调用函数是无法干扰其他对象的,划清了界限,也提高了我们整体的容错率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值