前言
最近在通过面试题对自己的基础进行一些查漏补缺,顺便记录一下📝 不想用题目的形式一题题写面试题的题解,这些已经有很多大佬整理得很好了,多看一看再梳理一下就能记住 我更希望以文章的形式去加深对某个知识点的理解,开锤
一道简单的题目:
function Person(name) {
this.name = name
}
// 函数对象上的方法
Person.say = function () {
console.log('----');
}
// 原型对象上的方法
Person.prototype.say = function () {
console.log('===');
}
const p = new Person('Tom')
// 函数对象执行的是函数对象的上方法 clg(---)
Person.say()
// 实例对象p执行的是原型对象上的方法 clg(===)
p.say()
当涉及到JavaScript中的对象、构造函数和原型时,有一些重要的概念需要理解。
在JavaScript中,构造函数是用于创建对象在例子中,Person 函数充当了构造函数的角色。当你使用 new 关键字来调用构造函数时,它会创建一个新的对象,并将属性和方法分配给这个对象。
function Person(name) {
this.name = name;
}
函数对象上的方法
一个有趣的特性是,JavaScript中的函数本身也是对象。这意味着你可以在函数对象上定义方法,这些方法可以被函数本身调用。在你的例子中,你定义了一个在 Person 函数对象上的 say 方法:
Person.say = function () {
console.log('----');
}
当你调用 Person.say() 时,它会在函数对象上执行这个方法,输出 ----。
原型对象上的方法
除了函数对象上的方法,JavaScript还提供了一种更为高效的方法共享机制,即原型。原型也是一个对象,每个构造函数都有一个关联的原型对象,你可以在原型对象上定义方法和属性,这些方法和属性会被由构造函数创建的对象共享。 (也就是会被new出来的实例对象共享)
在我们的例子中,定义了一个在 Person.prototype 上的 say 方法:
Person.prototype.say = function () {
console.log('===');
}
当你通过构造函数创建一个实例(例如 const p = new Person('Tom')),这个实例将继承原型上的方法。因此,p.say() 会输出 ===。
回过头来,让我们再看会这一段代码:
// 构造函数
function Person(name) {
this.name = name
}
// 函数对象上的方法
Person.say = function () {
console.log('----');
}
// 原型对象上的方法
Person.prototype.say = function () {
console.log('===');
}
const p = new Person('Tom')
// 函数对象执行的是函数对象的上方法 clg(---)
Person.say()
// 实例对象p执行的是原型对象上的方法 clg(===)
p.say()
我们就能够很好的理解为什么两种say方法执行输出的结果不同了,因为一个是函数对象,一个是实例对象,正因为函数的特殊性——JavaScript中的函数本身也是对象。所以才会有2种绑定say方法的方式。
理解这个概念对我们看api文档也很有帮助:
在翻阅Promise的Mdn文档的时候,我们可以看到有些方法是定义在Promise.prototype上的,而有的是直接定义在Promise上
定义在prototype上的方法,我们都是通过实例对象去调用,例如
const p = new Promise((resolve,reject)=>{
// ...
})
p.then() //用的是实例p去调用
而定义在Promise函数对象上的,例如reject的语法糖,我们是这么调用的
const rejectedPromise = Promise.reject('Something wrong.');
希望通过这个示例,能加深你对函数对象和实例对象的理解。