JavaScript普通函数与构造函数深度解析及区别
本文重点讲解JavaScript中普通函数与构造函数的本质区别,包括this上下文绑定、new实例化底层机制及返回值覆盖规则。
理解this的指向逻辑
this永远指向当前正在被执行的函数或方法的拥有者(owner)。要理解构造函数与普通函数的区别,首先明确this在不同调用场景下的表现:
- 全局环境调用:直接访问
this.name或在页面中定义的函数内部使用this,其指向window对象。 - 普通函数调用:
test()中的this同样指向window对象。 - 对象方法调用:
obj1.fn()中的this指向调用该方法的对象 obj1。 - 构造函数调用:
var dog=new Dog()中的this指向新创建的实例对象 dog。
此外,call 和 apply 可用于改变函数运行时的上下文。两者作用一致,区别仅在于接收参数的形式:call 接受多个单独参数,apply 接受一个参数数组。例如让 cat 对象借用 Dog 的方法:
// 定义Dog构造函数
function Dog(){
this.sound="汪汪汪";
}
Dog.prototype.bark=function(words){
alert(this.sound+" "+words);
}
// 定义cat对象
var cat={sound:'喵喵喵'};
// 使用call借调bark方法并传入参数
Dog.prototype.bark.call(cat,"饿了"); // 弹出 "喵喵喵 饿了"
普通函数的四大特征
普通函数(Regular Function)是JavaScript中最基础的单元,具有以下显著特点:
第1步:无需new关键字调用
直接使用括号执行即可:fn();
第2步:支持明确的return返回值
普通函数可以返回任意类型的值,且直接作为调用结果返回:
function fn(a,b){
return a+b;
}
console.log(fn(2,3)); // 输出 5
第3步:慎用this关键字
如果在普通函数内部使用this定义变量(如 this.name = "..."),因为此时this指向window全局对象,会导致无意间为window添加全局变量,极易引起命名冲突或内存泄露。
第4步:命名规范
按照约定,普通函数通常采用小驼峰命名法(camelCase),首字母小写。
构造函数的核心特性
构造函数主要用于创建特定类型的对象实例,使用 new 关键字进行调用。
第1步:必须用new关键字调用
示例:var prince=new Prince("charming", 25);
第2步:函数内部可使用this构建实例成员
在构造函数体内,this指向即将创建的新对象。使用this定义的变量和方法将成为实例属性/方法,只有通过实例才能访问:
function Prince(name, age) {
this.gender = "male";
this.name = name;
this.age = age;
}
Prince.prototype.toFrog = function() {
console.log("Prince " + this.name + " turned into a frog.");
};
var prince = new Prince("charming", 25);
prince.age; // 25 (可用)
Prince.age; // undefined (不可用)
第3步:默认返回this(新实例)
除非显式使用return语句返回对象类型值,否则构造函数默认返回this(即新创建的实例对象)。
第4步:命名规范
为了便于识别,构造函数的首字母通常建议大写(PascalCase)。
new关键字实例化的底层过程
当使用 new 调用构造函数时(以 new Prince() 为例),JavaScript引擎内部按以下顺序执行:
- 创建空对象:在内存中开辟一块空间,生成一个空的引用对象
{}。 - 绑定this:将构造函数内的this指向这个新创建的空对象。
- 连接原型:将该对象的内部原型
[[Prototype]](可通过__proto__访问)指向构造函数的prototype属性,建立继承关系。 - 执行代码:执行构造函数内部的代码块,为新对象的属性赋值。
- 返回对象:隐式返回该新对象(若未覆盖返回值)。
构造函数的返回值陷阱
构造函数中可以存在return语句,但其返回值处理遵循严格的规则:
- 返回原始数据类型(String、Number、Boolean、Null、Undefined):
JavaScript会忽略这些原始返回值,依然强制返回this对象(即新创建的实例)。 - 返回对象类型数据(Object、Array、Function等):
此时将不再返回this对象,而是直接返回return语句指定的那个对象。
验证示例:
function Person(name){
this.name = name;
return {name: "cherry"}; // 显式返回一个对象
}
var person = new Person("sheila");
person.name; // 输出 "cherry" (而非 "sheila")
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













