2023别再问我原型和原型链了,都在这
var code = "12e953e1-4869-42c9-89c2-808a7b15c77e"
前言
还记得第一次接触原型与原型链是在第一次,一晃4年已经过去了,期间也换过几次工作,每次面试最怕面试官问到原型链相关的知识,一问三不知,支支吾吾原地社死,哈哈哈
后面随着时间的积累,对此也有了一些了解,故此写下,欢迎交流!
一、原型
Js的原型是一种设计技术,它允许开发人员使用现有的对象创建新的对象,而不必重新编写代码。
市面上一般把原型分为隐式原型和显式原型:
(1)隐式原型:每个对象都有一个隐式原型__proto__,也叫指针,指向它的构造函数的原型对象。
(2)显式原型:每个函数都有一个prototype属性,指向它的原型对象,这个原型对象可以被实例化出来的对象所共享。
注意: 既是对象又是函数时,可以同时含有隐式原型和显式原型 (比如String、Number、Boolean、Object、Array、Function、Date、RegExp、Error、Symbol等,它们是使用new Function创建的内置函数,既有隐式原型又有显式原型)
console.log(Function.__proto__); //ƒ () { [native code] }
console.log(Function.prototype); //ƒ () { [native code] }
console.log(Function.__proto__ === Function.prototype); // true
// 因为Function是由new Function创建的,它们指向同一个对象,所以是true
二、原型链
原型链是一种对象的继承机制,基本原理是每个对象都有一个指向另一个对象的指针,这个指针叫做原型,它指向另一个对象,这个对象叫做原型对象。
当一个对象想要访问某个属性,如果本身没有,就会沿着__proto__一层一层的进行查找直到找到为止,顶层是null(防止死循环)。
面试官常问的一些相关方法:
- instanceof:用于检查构造函数的prototype属性是否出现在对象的原型链中。
- Object.prototype.hasOwnProperty():检查对象是否具有指定的属性。
- Object.prototype.isPrototypeOf():检查一个对象是否存在于另一个对象的原型链上。
- Object.prototype.propertyIsEnumerable():检查一个属性是否可以用for...in循环进行枚举。
- Object.getPrototypeOf():返回一个对象的原型对象。
- Object.setPrototypeOf():设置一个对象的原型对象。
- Object.create():创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
这张图可以很好的帮助初学者理解原型与原型链:
三、construct属性
- 只有对象才有construct属性,非对象没有
- construct属性是指向创建该对象的函数的指针,它指向函数的this,也就是说,construct属性指向函数的this对象。
let obj = {};
console.log(String.prototype.constructor === String); // true, String.prototype是一个对象,由 String创建
console.log(obj.construct === Object); // true, 由Object创建
console.log(String.constructor === Function); // true, 由Function创建
- constructor 会在创建对象实例时被调用。它可以用来设置实例属性或方法,也可以用来定义对象的初始化行为。
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
console.log(this.name, this.age);
}
}
// 创建一个Person对象
var person = new Person("John", 25);
// 调用sayHello方法
person.sayHello(); // John,25
后记
原型和原型链有时会被混淆,但它们是不同的概念。原型是一个对象,它可以被其他对象继承,而原型链是一种实现继承的方式,它可以让您从一个对象继承属性和方法到另一个对象。 总之,原型是一个对象,它可以被其他对象继承,而原型链是一种实现继承的方式。它们是 JavaScript 中对象的基础,可以让您从一个对象继承属性和方法到另一个对象。
码字不易,如果对你有帮助,还请点个赞以资鼓励!
真题训练
学习讲究学以致用,下面俺给各位老板准备了5道题,快来看看你是否能及格(满分100)。
// 1.
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
Person.prototype.name = 'Jack';
let person1 = new Person('John');
let person2 = new Person('Mary');
person1.sayName(); // John
person2.sayName(); // Mary
// 2.
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.sayBreed = function() {
console.log('My breed is ' + this.breed);
};
let dog = new Dog('Max', 'Labrador');
dog.sayName(); // My name is Max
dog.sayBreed(); // My breed is Labrador
// 3.
function A() {
this.name = 'A';
}
A.prototype.sayName = function() {
console.log(this.name);
}
function B() {
this.name = 'B';
}
B.prototype = new A();
B.prototype.sayHello = function() {
console.log('Hello ' + this.name);
}
var b = new B();
b.sayName(); // B
b.sayHello(); // Hello B
// 4.
function A () {}
A.prototype.age = 60;
var b = new A();
A.prototype = {
age: 18,
money: 0
}
var c = new A();
console.log(b.n, b.m); //35 undefined
console.log(c.n, c.m); //18 0
// 5.
function SuperCode(){
this.name = 'SuperCode';
this.age = 0;
}
SuperCode.prototype.getName = function(){
return this.name;
};
function SubCode(){
this.name = 'SubCode';
this.age = 1;
}
SubCode.prototype = new SuperCode();
SubCode.prototype.getAge = function(){
return this.age;
};
var instance = new SubCode();
console.log(instance.getName()); // SubCode
console.log(instance.getAge()); // 1