控制台输出:
每个“原型对象”中都有一个默认的属性,叫constructor, constructor 指向当前原型对象对应的那个“构造函数 <script> function Person(name, age) { this.name = name; this.age = age; } let obj1 = new Person("zs", 20); console.log(Person.prototype.constructor); </script>控制台输出:
通过构造函数创建出来的对象我们称之为"实例对象",每个"实例对象"中都有一个默认的属性,叫做__proto__ , __proto__指向创建它的那个构造函数的"原型对象" <script> function Person(name, age) { this.name = name; this.age = age; } let obj1 = new Person("zs", 20); console.log(obj1.__proto__); </script>控制台输出:
三者关系图:
4.JavaScript中函数是引用类型(对象类型),既然是对象,所以也是通过构造函数创建出来的,“所有函数”都是通过Function构造函数创建出来的对象
<script> console.log(Function); </script>控制台输出(说明存在Function构造函数): 5.JavaScript中只要是“函数”就要prototype属性
<script> console.log(Function.prototype); </script>控制台输出:
6.JavaScript中只要“原型对象”就有constructor属性,“Function“原型对象”的constructor指向它对应的构造函数
<script> function Person(name, age) { this.name = name; this.age = age; } let obj1 = new Person("zs", 20); console.log(Function.prototype.constructor); console.log(Function.prototype.constructor === Function); //说明Function原型对象”的constructor指向它对应的构造函数 console.log(Person.__proto__ === Function.prototype); //说明实例对象指向它的原型对象 console.log(Function.__proto__ === Function.prototype); //说明Function的__proto__指向它的原型对象 </script>控制台输出
关系图:
7.Object函数
在JavaScript中,有一个默认的函数名为Object,同样是通过构造函数Function创建出来的
先来看看Object有啥属性
<script> console.log(Object); console.log(Object.prototype); console.log(Object.__proto__); console.log(Object.constructor); </script>控制台输出: 关键:原型对象也是个对象,也有__proto__ 且__proto__ 指向null
<script> // Object 是 Function的实例对象,故Object的__proto__指向的是Function的原型对象 console.log(Object.__proto__ === Function.prototype); // Object是构造函数,有prototype属性 一个原型对象的constructor指向它的构造函数 console.log(Object.prototype.constructor === Object); //原型对象也是个对象,也有__proto__ console.log(Object.prototype.__proto__); </script>控制台输出:
关系图:
函数对象完整关系图:(重点)
原型链:
JavaScript中的原型链是根据以上的图进行查找,当实例对象的__proto__找不到时,就他的原型对象里找,还是找不到就会去Object中原型对象找,还没有就输出null
情况1:实例对象的__proto__已经定义
<script> function Person(name, age) { this.name = name; this.age = age; this.type = '构造函数中的人'; this.say = function() { console.log("构造函数中的Hello World"); } } Person.prototype = { type: '人', say: function() { console.log("Hello World"); } } let obj1 = new Person("zs", 20); let obj2 = new Person("ls", 25); console.log(obj1); obj1.say(); console.log(obj1.type); </script>控制台输出:
情况2:实例对象的__proto__没有定义,而他的原型对象Person.prototype已经定义
<script> function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { type: '人', say: function() { console.log("Hello World"); } } let obj1 = new Person("zs", 20); let obj2 = new Person("ls", 25); console.log(obj1); obj1.say(); console.log(obj1.type); </script>控制台输出:
优化建议:
<script> function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { type: '人', say: function() { console.log("Hello World"); } } console.log(Person.prototype.constructor); </script>控制台输出: 由以上可知,Person的原生对象指向了Object而不是Person,如何优化呢,只需手动修改 constructor属性即可
<script> function Person(name, age) { this.name = name; this.age = age; } Person.prototype = { constructor: Person, type: '人', say: function() { console.log("Hello World"); } } console.log(Person.prototype.constructor); </script>控制台输出: 总结点: (1)Function函数是所有函数的祖先函数 (2)所有构造函数都有一个prototype属性 (3)所有原型对象都有一个constructor属性 (4)所有函数都是对象 (5)所有对象都有一个__proto__属性
