js
2018-09-10 01:06:55来源:博客园 阅读 ()
js中的4种函数调用模式
javascript一共有4种调用模式:函数调用模式、方法调用模式、构造器调用模式和间接调用模式。
【1】函数调用模式
当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的。对于普通的函数调用来说,函数的返回值就是调用表达式的值
function add(x,y){
return x+y;
}
var sum = add(3,4);
console.log(sum)//7
使用函数调用模式调用函数时,非严格模式下,this被绑定到全局对象;在严格模式下,this是undefined
function add(x,y){
console.log(this);//window
}
add();
function add(x,y){
'use strict';
console.log(this);//undefined
}
add();//window
因此,’this’可以用来判断当前是否是严格模式
var strict = (function(){return !this;}());
重写
因为函数调用模式的函数中的this绑定到全局对象,所以会发生全局属性被重写的现象
var a = 0;
function fn(){
this.a = 1;
}
fn();
console.log(this,this.a,a);//window 1 1
【2】方法调用模式
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。如果调用表达式包含一个提取属性的动作,那么它就是被当做一个方法来调用
var o = {
m: function(){
console.log(1);
}
};
o.m();//1
方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this到对象的绑定发生在调用的时候。通过this可取得它们所属对象的上下文的方法称为公共方法。
var o = {
a: 1,
m: function(){
return this;
},
n: function(){
this.a = 2;
}
};
console.log(o.m().a);//1
o.n();
console.log(o.m().a);//2
任何函数只要作为方法调用实际上都会传入一个隐式的实参——这个实参是一个对象,方法调用的母体就是这个对象,通常来讲,基于那个对象的方法可以执行多种操作,方法调用的语法已经很清晰地表明了函数将基于一个对象进行操作
rect.setSize(width,height);
setRectSize(rect,width,height);
假设上面两行代码的功能完全一样,它们都作用于一个假定的对象rect。可以看出,第一行的方法调用语法非常清晰地表明这个函数执行的载体是rect对象,函数中的所有操作都将基于这个对象
和变量不同,关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。如果嵌套函数作为方法调用,其this的值指向调用它的对象。如果嵌套函数作为函数调用,其this值不是全局对象(非严格模式下)就是undefined(严格模式下)
var o = {
m: function(){
function n(){
return this;
}
return n();
}
}
console.log(o.m());//window
var o = {
m: function(){
function n(){
'use strict';
return this;
}
return n();
}
}
console.log(o.m());//undefined
如果想访问这个外部函数的this值,需要将this的值保存在一个变量里,这个变量和内部函数都同在一个作用域内。通常使用变量self或that来保存this
var o = {
m: function(){
var self = this;
console.log(this === o);//true
function n(){
console.log(this === o);//false
console.log(self === o);//true
return self;
}
return n();
}
}
console.log(o.m() === o);//true
【3】构造函数调用模式
如果函数或者方法调用之前带有关键字new,它就构成构造函数调用
function fn(){
this.a = 1;
};
var obj = new fn();
console.log(obj.a);//1
如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内
function fn(x){
this.a = x;
};
var obj = new fn(2);
console.log(obj.a);//2
如果构造函数没有形参,javascript构造函数调用的语法是允许省略实参列表和圆括号的。凡是没有形参的构造函数调用都可以省略圆括号
var o = new Object();
//等价于
var o = new Object;
[注意]尽管构造函数看起来像一个方法调用,它依然会使用这个新对象作为调用上下文。也就是说,在表达式new o.m()中,调用上下文并不是o
var o = {
m: function(){
return this;
}
}
var obj = new o.m();
console.log(obj,obj === o);//{} false
console.log(obj.constructor === o.m);//true
构造函数通常不使用return关键字,它们通常初始化新对象,当构造函数的函数体执行完毕时,它会显式返回。在这种情况下,构造函数调用表达式的计算结果就是这个新对象的值
function fn(){
this.a = 2;
}
var test = new fn();
console.log(test);//{a:2}
如果构造函数使用return语句但没有指定返回值,或者返回一个原始值,那么这时将忽略返回值,同时使用这个新对象作为调用结果
function fn(){
this.a = 2;
return;
}
var test = new fn();
console.log(test);//{a:2}
如果构造函数显式地使用return语句返回一个对象,那么调用表达式的值就是这个对象
var obj = {a:1};
function fn(){
this.a = 2;
return obj;
}
var test = new fn();
console.log(test);//{a:1}
【4】间接调用模式
javascript中函数也是对象,函数对象也可以包含方法。call()和apply()方法可以用来间接地调用函数
这两个方法都允许显式指定调用所需的this值,也就是说,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是那个对象的方法。两个方法都可以指定调用的实参。call()方法使用它自有的实参列表作为函数的实参,apply()方法则要求以数组的形式传入参数
var obj = {};
function sum(x,y){
return x+y;
}
console.log(sum.call(obj,1,2));//3
console.log(sum.apply(obj,[1,2]));//3
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:es6 常用方法
- JavaScript函数表达式详解及实例 2020-03-25
- Javascript中的经典技巧 2020-03-20
- 带你了解JavaScript中的函数 2020-03-08
- 默认让页面的第一个控件选中的javascript代码 2020-02-20
- 详谈构造函数加括号与不加括号的区别 2020-01-17
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash