原型和原型对象的区别和对应关系
1.原型和原型对象的所属关系
(a)作为构造函数具有原型对象(原型对象中嵌有原型),且含有原型.
(b)作为构造函数创建出并不作为构造函数的实例对象,没有原型对象,只有原型且嵌有原型
2.原型和原型对象的访问写法
(a)原型访问:对象名.__proto__,实际名称为[[prototype]]
(b)原型对象访问:对象名.prototype
3.原型和原型对象在创建时形成的继承关系
代码:var 实例对象名 = new 构造函数名(参数)
(1)由new创建一个空对象
(2)将构造函数中的原型对象prototype引用且复制到实例对象中的原型[[prototype]]
(3)调用构造函数中的执行语句,this指当前new创建的空对象
(4)在内存中为实例对象创建空间,分配地址
原型链
1.原型链的构成
例1:
<script>
function add(){
var n = 1;
}
var add1 = new add();
</script>
//1.这里的原型链属于add1的原型(等价于add的原型对象)
//add1.__proto__ == add.prototype
//add1.__proto__.__proto__ == add.prototype.__proto__ == Object.prototype
//add1.__proto__.__proto__.__proto__ == add.prototype.__proto__.__proto__ == Object.prototype.__proto__ == null
//2.这里的原型链属于add函数的原型
//add.__proto__ == Function.prototype
//add.__proto__.__proto__ == Function.prototype.__proto__ == Object.prototype
//add.__proto__.__proto__.__proto__ == Object.prototype.__proto__ == null
2.原型链的访问机制(依次往下)
(1)先去检查对象上的属性.若有,则调用对象上的属性.
(2)若对象上的属性没有,则遍历原型链中去查找属性.若有,则调用原型链上的属性
(3)若原型链上没有这个属性,则返回undefined
3.查找原型链中是否含有属性
(1)一般情况,进行访问,则会遍历整个原型链导致性能变差
(2)使用Object.hasOwnProperty()方法,不会遍历原型链,且会返回true或false来表达结果
4.生成原型链的方法
(1)使用语法结构创建的对象
var 对象名 = /\d{9}/
console.log(a.__proto__ == RegExp.prototype);//true
(2)使用构造函数创建的对象
function add(){var n = 1;}
var add1 = new add();
console.log(add1.__proto__ == add.prototype);//true
(3)Object.create()创建的对象
var a = {b:1};
var b = Object.create(a);
console.log(b.__proto__ == a);//true
(4)使用class关键字创建的对象
5.函数和类的关系
class Dog{
constructor(name,age){
this.name = name;
this.age = age;
}
eat(){
console.log('eat');
}
}
等于
function Dog(name,age){
this.name = name;
this.age = age;
}
Dog.prototype.eat = function(){
console.log('eat');
}
const dog = new Dog('包子',3);