转载 https://blog.csdn.net/weixin_44976833/article/details/101322081
构造函数和原型和原型链
1.静态成员和实例成员
1.1静态成员
静态成员在构造函数本身上添加的成员,静态成员只能通过构造函数来访问
function Person(name,age){this.name = name;this.age = age;
}
//sex就是静态成员
Person.sex = '男';
var one = new Person('小明',12);
console.log(Person.sex); //静态成员只能通过构造函数来访问
1.2实例成员
实例成员就是构造函数内部通过this添加的成员,实例成员只能通过实例化的对象来访问;
//nam,age,study就是实例成员
function Person(nam,age){this.nam = nam;this.age = age;this.study = function(){console.log('我再认真学习js');}
}
var one = new Person('小明',12);
console.log(one.study); //实例成员只能通过实例化对象来访问
2.构造函数原型prototype
构造函数通过原型分配的函数是所有对象所共享的,规定每一个构造函数都有一个prototype属性,指向另一个对象,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有的,可以把那些不变的方法直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法;
3.对象原型__proto__
1.对象都会有一个属性__proto__ 指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__prorto__原型的存在;
2.__proto__对象原型和原型对象prototype是相等的;
3.__proto__对象原型的意义就是在于为对象查找机制提供一个方向,但是它是一个非标准属性,实际开发中不可以使用这个属性,它只是内部指向原型对象prototype;
4.constructor构造函数
1.对象原型__proto__和构造函数prototype原型对象里面都有一个属性constructor属性,constructor称为构造函数,因为它指回构造函数本身;
2.constructor主要是用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数;
3.一般情况下,对象的方法都在构造函数的原型对象中设置,如果有多个对象方法,我们可以给对象采用对象形式赋值,但是这样就会覆盖构造函数原型对象原来的内容,修改后的原型对象constructor就不在指向当前构造函数,此时可以在修改后的原型对象中,添加一个constructor指向原来的构造函数
function Person(uname, age) {this.uname = uname;this.age = age;}// 很多情况下,我们需要手动的利用constructor 这个属性指回 原来的构造函数
Person.prototype = {// 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数// 手动设置指回原来的构造函数constructor: Person, sing: function() {console.log('我唱歌很好听');},study: function() {console.log('我正在学习js');}
}
var one = new Person('小明', 18);
5.构造函数实例和原型对象三角关系
1.构造函数的prototype属性指向了构造函数原型对象;
2.实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象;
3.构造函数的原型对象的constructor属性指向了构造函数,实例对象原型的constructor属性也指向了构造函数;
6.原型链和成员的查找机制
任何对象都有原型对象,也就是prototype属性,任何原型对象也是一个对象,该对象有__proto__属性,这样一层一层往上找,就会形成一条链,原型链;
1.当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
2.如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
3.如果还没有就查找原型对象的原型(Object的原型对象)。
4.依此类推一直找到 Object 为止(null)。
5.__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。