探讨JavaScript原型和原型链
原型和原型链
js没有类和对象的概念,但是有原型和原型链的概念,这JavaScript中的原型是指每个对象在创建的时候都会关联到另一个对象,这个对象就是该对象的原型,而原型链是指当访问一个对象的属性或方法的时候,如果该对象本身没有这个属性或方法,JavaScript就会沿着原型链向上查找,直到找到对应的属性和方法位置。
- 原型链的作用在于实现了对象之间的继承关系
- 原型的作用
-
当我们通过引用对象的属性key来获取value的时候,他会触发get的操作
-
这个操作会首先检查该对象是否有对应的属性,如果有就使用它
-
如果对象中没有该属性,那么会访问对象prototpe内置属性指向的对象上的属性
-
如下是前端圈火热的JavaScript继承图,可以更好的看出来原型和原型链以及继承的关系
-现在对上图进行解释,前置知识:
- 每创建一个函数,就会同时创建它的prototype对象,所有的函数都有一个prototype的属性,这是函数对应的原型对象
- 所有的原型对象都有constructor属性,它是用来指向当前的函数对象
// 非常重要的属性: constructor, 指向Person函数对象
function Person() {
}
// 1.对constructor在prototype上的验证
var PersonPrototype = Person.prototype
console.log(PersonPrototype)//Object 内含constructor
console.log(PersonPrototype.constructor)//function Person
console.log(PersonPrototype.constructor === Person)//true
console.log(".............");
console.log(Person.name)//Person
console.log(PersonPrototype.constructor.name)//Person
- JavaScript原型链,当一个对象上获取属性,如果在当前对象没有获取到就回去它的原型上面获取
// 2.原型链
var obj = {
name: "why",
age: 18
}
// 查找顺序
// 1.obj上面查找
// 2.obj.__proto__上面查找
// 3.obj.__proto__.__proto__ -> null 上面查找(undefined)
// console.log(obj.message)
// 3.对现有代码进行改造
obj.__proto__ = {
// message: "Hello aaa"
}
obj.__proto__.__proto__ = {
message: "Hello bbbb"
}
obj.__proto__.__proto__.__proto__ = {
message: "Hello ccc"
}
console.log(obj.message)
- Object是一个内置的构造函数,用于创建对象,他是原型链的尽头,是所有类的父类
const person = {
name: 'John',
age: 30,
greet: function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
};
console.log(person.constructor === Object); // 输出: true
- Function是一个内置的构造函数,用与创建函数对象,他是所有函数的类,因为JavaScript函数实际上都是Function类型的实例
function add(a, b) {
return a + b;
}
console.log(add.constructor === Function); // 输出: true
- 内置对象还有Array 、 Date 这些都是浏览器引擎给我们的,JavaScript内置的构造函数
- prototype和_proto_之间的区别,其中prototype用于对象的原型链,_proto_用于实例的原型链,当你使用new关键词的时候,这就是实例化操作。当你用new创建一个对象的时候,JavaScript会自动为这个对象添加_proto_属性,并且这个对象指向函数的原型
function Get(name){
this.name = name
}
Get.prototype.sayhello = function(){
console.log("hello")
}
const set = new Get("111")
console.log(Get.prototype === set.__proto__)//true
- 如下是其他版本图,原理和指向都是一样的。选择自己最喜欢的去学习即可
好,现在我们学完了前置知识,我们来解析这张js的经典继承图,所有的函数和函数原型之间的关系都是相互的如下图视
有几个重点,就是new出来的实例化函数,他是有_proto_属性的,并且这个per1.proto 指向person的原型对象的,这些全部的_Proto_最终都指向Object.prototype,因为Object是他们尽头,Object.prototype的_proto_指向null
构造函数实现继承
因为JavaScript中没有类和对象的概念,JavaScript的设计者使用构造函数来实现继承机制
转载自:https://juejin.cn/post/7355414702434320403