JS 原型链中【__proto__】【prototype】 属性的区别
先定义一个 User 函数 【即下文中所有的 本对象】
围绕这个函数的 【__proto__】 和 【prototype】 属性进行对比试验
function User() {}
__proto__将属性绑定到父对象上
在此例中,即绑定到 Object 对象上
作用:【可供所有兄弟对象使用】
执行操作:绑定 brotherShow 属性到 User 父对象上
// 1.绑定前 - Object.brotherShow 属性未定义
console.log(Object.brotherShow); // undefined
// 2.绑定中 - 利用 __proto__ 属性进行绑定操作
User.__proto__.brotherShow = function() {
console.log("brotherShow")
}
// 3.绑定后 - Object.brotherShow 属性为函数实体
console.log(Object.brotherShow); // 函数实体
声明更多的 Object 的子对象 即 User 的兄弟对象,来验证操作:
// User的兄弟对象 1
function brother1OfUser() {}
// 当 brother1OfUser 本身不存在 brotherShow 方法时
// 会利用 __proto__ 去父对象上寻找
brother1OfUser.brotherShow(); // brotherShow
// User的兄弟对象 2
function brother2OfUser() {}
// 与上例同理
brother2OfUser.brotherShow(); // brotherShow
prototype 将属性绑定到本对象实例上【而非 本对象】
执行操作:绑定 sonShow 属性到 User 实例上:
User.prototype.sonShow = function() {
console.log("sonShow");
}
意味着本对象无法直接调用:
console.log(User.sonShow); // undefined
声明本对象的实例并打印输出,来验证操作:
let son1 = new User();
son1.sonShow(); // sonShow
let son2 = new User();
son2.sonShow(); // sonShow
结论:
- User 的兄弟对象 可访问绑定到【__proto__】 上的方法【例:brotherShow】
- User 的对象实例 可访问绑定到 【prototype】上的方法【例:sonShow】
扩展思考:
__proto__中绑定的函数 brotherShow(), 绑定到原型链的哪个顶级对象上去了
// 在函数对象中 【__proto__ 隐式原型】 存储的是 构造函数的 【prototype 显式原型】的值
function User0() {} // User0 = new Function();
function User1() {} // User1 = new Function();
function User2() {} // User2 = new Function();
function User3() {} // User3 = new Function();
console.log(User0.__proto__ === Function.prototype); // true
console.log(User0.__proto__ === User1.__proto__); // true
console.log(User1.__proto__ === User2.__proto__); // true
console.log(User2.__proto__ === User3.__proto__); // true
console.log(Object.__proto__ === Function.prototype); // true
// 特殊 Function 函数对象的隐式原型和显式原型相同
console.log(Function.__proto__ === Function.prototype); // true
console.log(son1.__proto__ === User.prototype); // true
console.log(User.prototype.__proto__ === Object.prototype); // true
// console.dir(Object.prototype); // 已经到达最顶级
// 隐式原型和显式原型相同
Function.prototype.brotherShow(); // brotherShow
Function.__proto__.brotherShow(); // brotherShow
附全部代码如下:
<script type="text/javascript">
// 先定义一个 User 函数 【即下文中所有的 本对象】
// 围绕这个函数的 【__proto__】 和 【prototype】 属性进行对比试验
function User() {}
// __proto__ 是将属性绑定到父对象上
// 在此例中,即绑定到 Object 对象上
// 作用:【可供所有兄弟对象使用】
// 执行操作:绑定 brotherShow 属性到 User 父对象上
// 1.绑定前 - Object.brotherShow 属性未定义
console.log(Object.brotherShow); // undefined
// 2.绑定中 - 利用 __proto__ 属性进行绑定操作
User.__proto__.brotherShow = function() {
console.log("brotherShow")
}
// 3.绑定后 - Object.brotherShow 属性为函数实体
console.log(Object.brotherShow); // 函数实体
// 声明更多的 Object 的子对象 即 User 的兄弟对象,来验证操作:
// User的兄弟对象 1
function brother1OfUser() {}
// 当 brother1OfUser 本身不存在 brotherShow 方法时
// 会利用 __proto__ 去父对象上寻找
brother1OfUser.brotherShow(); // brotherShow
// User的兄弟对象 2
function brother2OfUser() {}
// 与上例同理
brother2OfUser.brotherShow(); // brotherShow
// ================华丽的分割线========================
// prototype 是将属性绑定到本对象实例上【而非 本对象】
// 执行操作:绑定 sonShow 属性到 User 实例上:
User.prototype.sonShow = function() {
console.log("sonShow");
}
// 意味着本对象无法直接调用
console.log(User.sonShow); // undefined
// 声明本对象的实例并打印输出
let son1 = new User();
son1.sonShow(); // sonShow
let son2 = new User();
son2.sonShow(); // sonShow
// 结论:
// User 的兄弟对象 可访问绑定到【__proto__】 上的 【brotherShow】 方法
// User 的对象实例 可访问绑定到 【prototype】上的 【sonShow】 方法
// 在函数对象中 【__proto__ 隐式原型】 存储的是 构造函数的 【prototype 显式原型】的值
function User0() {} // User0 = new Function();
function User1() {} // User1 = new Function();
function User2() {} // User2 = new Function();
function User3() {} // User3 = new Function();
console.log(User0.__proto__ === Function.prototype); // true
console.log(User0.__proto__ === User1.__proto__); // true
console.log(User1.__proto__ === User2.__proto__); // true
console.log(User2.__proto__ === User3.__proto__); // true
console.log(Object.__proto__ === Function.prototype); // true
// 特殊 Function 函数对象的隐式原型和显式原型相同
console.log(Function.__proto__ === Function.prototype); // true
console.log(son1.__proto__ === User.prototype); // true
console.log(User.prototype.__proto__ === Object.prototype); // true
// console.dir(Object.prototype); // 已经到达最顶级
// 隐式原型和显式原型相同
Function.prototype.brotherShow(); // brotherShow
Function.__proto__.brotherShow(); // brotherShow
</script>