前言
原型
是函数上的一个属性,它定义了构造函数制造的对象的公共祖先。
原型链
js引擎在查找属性时,会顺着对象的隐式原型(这个在下面会进行介绍)向上查找,找不到则查找隐式原型的隐式原型,一直向上,直到找到null为止,这种查找关系称之为原型链。
正文
原型
ini
复制代码
Person.prototype.lastName = 'lt'; Person.prototype.say = function() { console.log('素~'); } function Person() { this.name = 'lxp'; } let p1 = new Person(); //隐式具有 lastName say console.log(p1); console.log(p1.lastName); p1.say();

分析
定义了一个p1对象,该对象会继承构造函数Person内的name属性(显式属性),并且p1的原型会继承构造函数Person的原型(隐式原型),所以当查找lastName属性时会先先查找p1的显示属性中有没有,如果没有就会查找隐式原型中有没有该属性。
ini
复制代码
Car.prototype.name = 'su7'; Car.prototype.height = 1400; Car.prototype.lang = 5000; function Car(color, owner) { this.color = color; this.owner = owner; } let ltt = new Car('black', 'ltt'); let lxp = new Car('purple', 'lxp'); console.log(ltt.name);
![]()
分析
对于构造函数Car,我们会把它的name,lang,height(因为Car的这些属性是设定好的)放在它的原型上,然后它的name和owner会通过接收两个参数来实现。
ini
复制代码
Car.prototype.producter = 'xiaomi' function Car() { this.name = 'su7'; } let car = new Car(); console.log(car); console.log(car.producter);

添加代码
ini
复制代码
car.name = '红旗'; car.producter = 'huawei';

可以打开一个网页,在控制台运行代码来查看原型上的nickname是否改变。显然是没有改变的

分析
实例对象可以修改显示继承到的属性,但是无法修改隐式继承到的属性(原型上的)。
添加代码
ini
复制代码
car.nickname = 'ltt';

ini
复制代码
Car.prototype.nickname = 'ltt';

分析
实例对象无法给原型新增属性。
添加代码
arduino
复制代码
delete car.producter;

javascript
复制代码
delete Car.prototype.producter;

分析
实例对象无法删除原型上的属性。
总结
构造函数new出来的对象会隐式继承到构造函数原型上的属性。
- 实例对象可以修改显示继承到的属性,但是无法修改隐式继承到的属性(原型上的);
- 实例对象无法给原型新增属性;
- 实例对象无法删除原型上的属性。
javascript
复制代码
function Bus() {} Car.prototype = { constructor: Bus } function Car() { } let car = new Car(); console.log(car.constructor); //记录该对象是由谁创建的
![]()
分析
constructor是记录该对象由谁创建的。
原型链
创建一个html,便于去控制台查看
xml
复制代码
<script> function Person() { } let p =new Person(); console.log(Person.prototype);//函数原型 显式原型 console.log(p.__proto__); // p.__proto__ 对象的原型 隐式原型 //Person.prototype === p.__proto__ //Person.prototype.__proto__ === object.prototype //object.prototype.__proto__ === </script>


分析
Person.prototype(函数原型 显式原型) === p.__proto__(对象的原型 隐式原型)Person.prototype.__proto__ === object.prototype
总结
-
对象的隐式原型 === 创建它的构造函数的显示原型
-
js引擎在查找属性时,会先查找对象显示具有的属性,找不到,再查找对象的隐式原型(
__proto__)
ini
复制代码
GrandFather.prototype.say = function() { console.log('haha'); } function GrandFather() { this.age = 60; this.like = 'drink'; } Father.prototype = new GrandFather(); function Father() { this.age = 40; this.fortune = { card: 'visa' } } Son.prototype = new Father(); function Son() { this.age = 18; } let son =new Son();
测试代码
arduino
复制代码
console.log(son.age);//18
![]()
测试代码
arduino
复制代码
console.log(son.fortune);
![]()
测试代码
arduino
复制代码
console.log(son.like);
![]()
测试代码
ini
复制代码
son.say();
![]()
总结
js引擎在查找属性时,会顺着对象的隐式原型向上查找,找不到则查找隐式原型的隐式原型,一直向上,直到找到null为止,这种查找关系称之为原型链。
结语
最后让我们来思考一个问题:所有的对象都有原型? 答案:不 Object.create(null) 没有原型。
实例
创建一个html
xml
复制代码
<script> let a ={ name:'ltt' } let obj = Object.create(a);//创建一个新对象,让新对象隐式继承 a 对象的属性 console.log(obj); </script>

分析
Object.create(a) 创建一个新对象,让新对象隐式继承 a 对象的属性。
添加代码
javascript
复制代码
let obj1 = Object.create(null);//该对象没有原型 console.log(obj1);

分析
Object.create(null)创建的对象没有原型。


被折叠的 条评论
为什么被折叠?



