函数调用、方法调用及构造函数调用之间的不同
程序员文章站
2024-03-26 11:24:35
...
最简单的使用模式是函数调用:
function hello(username){
return "hello,"+username;
}
hello("Keyser Soze");//"hello,Keyser Soze"
第二种使用模式是方法调用。JavaScript中的方法不过是对象的属性恰好是函数而已。
var obj ={
hello:function(){
return"hello,"+this.username;
},
username:"Hans Gruber"
};
obj.hello();//"hello,Hans Gruber"
var obj2={
hello:obj.hello,
username:"Boo Radley"
};
obj2.hello();//"hello,Boo Radley"
事实是,在方法调用中是由调用表达式自身来确定this变量的绑定,绑定到this变量的对象被称为调用接收者。表达式obj.hello()在obj对象中查找名为hello的属性,并将obj对象作为接收者,然后调用该属性。表达式obj2.hello()在obj2对象中查找名为hello的属性,恰好正是obj.hello函数,但是接收者是obj2对象,通常,通过某个对象调用方法将查找该方法并将该对象作为该方法的接收者。
由于方法其实就是通过特定对象调用的函数,但不知为何一个普通的函数不能引用this变量。
function hello(){
return "hello,"+this.username;
}
var obj1={
hello:hello,
username:"Gordon Gekko"
};
obj1.hello();//"hell"o,Groden Gekko"
var obj2 ={
hello:hello,
username:"Biff Tannen"
};
obj2.hello();//"hello Biff Tannen"
然而,使用了一个this变量的函数,比起作为方法被调用,将它作为函数被调用并不是特别有用。
hello();//"hello,undefinde"
一个 非方法的函数调用会将全局对象作为接收者,在这种情况下全局对象没有名为name的属性所以产生了undefined。如果方法中需要使用this变量,则将方法作为函数调用则毫无用处,因为没理由希望全局对象匹配调用对象中的方法。事实上,将this变量绑定到全局对象是没问题的,所以ES5的严格模式将this变量的默认绑定值改为undefined。
function hello(){
"use strict";
return "hello,"+this.username;
}
hello();//error:cannot read property "username" of undefined
这有助于更快的捕获偶然的将方法错误的作为纯函数使用的情况。因为试图访问undefined的属性会立即抛出一个错误。
第三种用法是通过构造函数使用。
function User(name,passwordHash){
this.name = name;
this.passwordHash = passwordHash;
}
使用new操作符来调用User则视为构造函数。var u = new User("sfalken","0effagsgfs143657fdgfddf1116796");
u.name;//"sfalken"
与函数调用和方法调用不同的是,构造函数调用将一个全新的对象作为this变量的值,并隐式返回这个新对象作为调用结果。构造函数的主要职责是初始化该新对象。
总结:
方法调用将被查找方法属性的对象作为调用接收者。
函数调用将全局对象作为其接收者,一般很少使用函数调用语法来调用方法。
构造函数需要通过new运算符调用,并产生一个新的对象作为其接收者。
上一篇: C++类析构函数
下一篇: C++知识点总结1 基础知识点