美文网首页深入JavaScript
深入JavaScript Day10 - 【重点】原型链、认识O

深入JavaScript Day10 - 【重点】原型链、认识O

作者: 望穿秋水小作坊 | 来源:发表于2022-01-17 11:38 被阅读0次

一、原型链、认识Object

1、对于下面代码,描述查找name的过程?(理解原型链是什么)

var obj = {};
console.log(obj.name);
  • obj找name属性的时候,会触发[[get]]操作
  • 在obj对象内没找到,就会去obj.__proto__ 中查找
  • obj.__proto__ 也是一个对象,也有 __proto__ 属性,所以再会去 obj.__proto__.__proto__中查找
  • 直到找到顶层原型,这时 __proto__ 属性 指向 null,表示未找到,返回 undefined
  • 上述原型直接形成的链状结构,就是原型链
image.png

2、var obj = {} 是一个快速创建对象的语法糖,语法原形是什么?

var obj = new Object()

3、顶层原型到底是谁?如何证明?为什么需要有顶层原型?

  • 顶层原型是 Object函数
  • 如果没有顶层原型,那么[[get]]操作,就会沿着原型链进入查找的死循环
var obj = {};
console.log(obj.__proto__.__proto__); // null
console.log(obj.__proto__ === Object.prototype); // ture

image.png

4、Object的本质是什么?

  • 很多人把它称为《类》,本质上它是函数
  • JavaScript中的所有类,本质上都是函数。
console.log(typeof Object); // function
console.log(typeof Object.prototype); // object
console.log(Object.prototype.__proto__); // null

5、Object是所有类的父类吗?

image.png image.png

二、理解继承

1、【重点掌握】绘制下面代码对应的内存图,并且思考打印结果?

  this.name = "why";
}

Person.prototype.running = function () {
  console.log(this.name + " 在跑步~");
};

function Student() {}

var p = new Person();
Student.prototype = p;

Student.prototype.studying = function () {
  console.log(this.name + " 在学习~");
};

var stu1 = new Student();
stu1.no = 100;
stu1.name = "lsp";
console.log(stu1);
console.log(stu1.__proto__);
console.log(stu1.__proto__.__proto__);
console.log(stu1.__proto__ === p);
stu1.studying();
stu1.running();

var stu2 = new Student();
stu2.no = 200;
console.log(stu2);
stu2.studying();
stu2.running();
  • 上述代码,在node环境删除
Person { no: 100, name: 'lsp' }
Person { name: 'why', studying: [Function (anonymous)] }
{ running: [Function (anonymous)] }
true
lsp 在学习~
lsp 在跑步~
Person { no: 200 }
why 在学习~
why 在跑步~
image.png image.png

2、上面我们实现了继承体系,但是上面体系存在两大问题?

  • ①我们在创建Person或者Student的时候,不好传递参数
  • ②如果Person里面有个数组属性(引用类型数据),stu1对数组进行push操作,会同时影响到stu2

3、如何解决上述问题呢?

  • 【借用构造函数】Person.call(this, name, friends);
function Person(name, friends) {
  this.name = name;
  this.friends = friends;
}

Person.prototype.running = function () {
  console.log(this.name + " 在跑步~");
};

function Student(name, no, friends) {
  Person.call(this, name, friends);
  this.no = no;
}

var p = new Person();
Student.prototype = p;

Student.prototype.studying = function () {
  console.log(this.name + " 在学习~");
};

var stu1 = new Student("lsp", 100, []);
stu1.friends.push("lucy");
console.log(stu1);
console.log(stu1.friends);
console.log(stu1.__proto__);
console.log(stu1.__proto__.__proto__);
console.log(stu1.__proto__ === p);
stu1.studying();
stu1.running();

var stu2 = new Student("why", 200, []);
console.log(stu2.friends);
console.log(stu2);
stu2.studying();
stu2.running();
  • 上述代码输出
Person { name: 'lsp', friends: [ 'lucy' ], no: 100 }
[ 'lucy' ]
Person {
  name: undefined,
  friends: undefined,
  studying: [Function (anonymous)]
}
{ running: [Function (anonymous)] }
true
lsp 在学习~
lsp 在跑步~
[]
Person { name: 'why', friends: [], no: 200 }
why 在学习~
why 在跑步~
image.png image.png

4、上述【借用构造函数】存在2大缺点?

  • Person函数至少被调用2次
  • stu的原型上会多出一下属性,这些属性都是没存在必要的
image.png

5、JavaScript实现继承的完整版思路和方案?

image.png image.png

相关文章

网友评论

    本文标题:深入JavaScript Day10 - 【重点】原型链、认识O

    本文链接:https://www.haomeiwen.com/subject/eacchrtx.html