JavaScript 函数调用的四种方式与区别

  最近出了一些事情,很久没有写博客了,再次拿起也不知道要写什么,偶然阅读到一篇文章。本篇短文大部分内容出自《JavaScript语言精粹》一书,有兴趣的同学可以去购买阅读,很棒的一本书,是js大师 道格拉斯·克罗克福德 的作品,不适合初学者。

  调用一个函数时,会暂停当前函数的执行,传递控制权和参数给新函数(被调用的函数)。除了被调用的函数声明时的形参,每个函数还接收两个附加的参数:this和arguments。参数this在面向对象编程中非常重要,它的值取决于调用的模式。在JavaScript中函数有4种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply(call)调用模式。这些调用模式在如何初始化this上存在差异。

  

  方法调用模式

  当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个对象的方法被调用时,this被绑定到调用方法的对象。

var myObj = {
	name : "MT",
	setName : function(name){
		this.name = name;
	}
};

myObj.setName("哀木涕");
console.log(myObj.name);	//"哀木涕"

myObj.setName("小德");
console.log(myObj.name);	//小德

  方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this和对象的绑定发生在方法调用的时候。这个“超级”延迟绑定(vary late binding)使得函数可以对this高度复用。通过this可以取得它们所属对象的上下文方法称为公共方法(public method)。

 

 函数调用模式

  当一函数并非一个对象的属性时,那么它就是被当做一个函数来调用的:

var sum = add(1,2);    //sum的值为3。

  以此模式调用函数时,this被绑定到全局对象。这是语言设计上的一个错误。倘若语言设计正确,那么当内部函数被调用时,this应该仍然绑定到外部函数的this变量。这个设计错误的后果就是方法不能利用内部函数来帮助它工作,因为内部函数的this被绑定了错误的值(全局对象),所以不能共享该方法对对象的访问权。幸运的是,有一个很容易的解决方案:如果一个对象的方法定义了一个变量并将this赋值给它,那么内部函数就可以通过那个变量访问到外部方法调用的对象。按照约定,我们把那个变量命名为that:

myObj.changeName = function(){
	var that = this;	//解决方法
	
	var change = function(){
		that.name = "change" + that.name;
	}
	
	change();	//以函数的方式调用change;
}

//以方法的形式调用changeName。
myObj.changeName();
console.log(myObj.name);

  

 构造器调用模式

  JavaScript是一门基于原型继承的语言。这意味着对象可以直接从其他对象继承属性。该语言是无类型的。

  如果在一个函数前面带上 new 关键字来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象,同时this会被绑定到那个新对象上。

  new 前缀也会改变return 语句的行为,如果return 的值是对象,那么将会将这个对象返回,否则将返回默认创建的新对象。

//创建一个名为Person的构造器函数。它构造一个带有name属性的对象。
function Person(howName){
	this.name = howName;
}

Person.prototype.getName = function(){
	return this.name;
}

var person = new Person("MT");
console.log(person.getName());

  一个函数,如果创建的目的就是希望结合new前缀来调用,那它就被称为构造器函数。按照约定,它们保存在以大写格式命名的变量里。如果调用构造函数时没有在前面加上new ,可能会发生非常糟糕的事情,(这时将会以函数的方式调用,由于函数的方式调用this是全局对象,这时不会返回新对象,而是在全局对象上添加属性。)既没有编译时警告,,也没有运行时警告,所以大写约定非常重要。

 

 apply/call调用模式

  因为JavaScript是一门函数式的面向对象编程语言,所以函数可以拥有方法。

  apply/call方法允许我们选择this的值。apply方法接受两个参数,第一个是要绑定的this的值,第二个参数是参数数组。call方法第一个参数是要绑定的this的值,后面紧跟的是相关的参数。

function setAge(age){
	this.age = age;
}

setAge.call(myObj, 23);	
console.log(myObj.age);		//23

setAge.apply(myObj, [24]);
console.log(myObj.age);		//24

  

  

 

转载于:https://www.cnblogs.com/miracle-t/p/6047794.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值