七、对象基础 (一) -- 原型继承
作者:互联网
一、原型
在Javascript中,万物皆对象。
JS中对象大致可以分为两类,即:普通对象Object 和 函数对象Function。
一般而言,通过new Function产生的对象是函数对象,其他对象都是普通对象。
1.1 原型对象
1、所有的函数都自带一个’prototype’属性,可称为原型属性。
这个原型属性指向了一个原型对象。(原型对象就是一个普通的对象)
2、所有的对象(包含函数对象)都自带一个’__proto__'属性,可称为隐式原型。
这个隐式原型指向它的构造函数的’prototype’属性。
3、原型对象就是一个公共区域,所有实例共享。
1)所有的函数都自带一个prototype属性,这个属性指向原型对象
function sayName(){
console.log(this.name);
}
console.log(sayName.prototype)
2)所有的对象都自带一个__proto__属性,这个隐式原型属性指向该构造函数的’prototype’属性。
function Person(){
console.log('this.name');
}
var s=new Person();
console.log(Person.prototype);
console.log(Person.prototype == s.__proto__);
3)原型对象是一个公共区域,所有实例共享。
function MyClass(){
console.log('this.name');
}
var s=new MyClass();
var s2=new MyClass();
console.log(s.__proto__==s2.__proto__); //true
1.2 原型对象的作用:原型继承
js通过原型对象实现类的继承关系。所有对象都从原型对象中继承属性和方法
1、原型对象就是一个公共区域,所有实例共享。
所有对象都从原型对象中继承属性和方法
2、原型链:原型对象的原型对象...
1) 当访问一个对象的属性或方法时,它首先会在自身的作用域中查找。
2) 如果没有则会通过原型对象中查找。
3) 如果仍没有则会通过原型对象的原型对象查找。
4) 依次查找,直到Object.prototype。
3、原型链查找以__proto__为链接 。
Object.prototype 是原型链的顶端。它的原型为null。
1)原型对象就是一个公共区域,所有实例共享。所有对象都从原型对象中继承属性和方法。
function MyClass(){
}
MyClass.prototype.sayName=function(){
console.log("23")
}
var s=new MyClass();
s.sayName();
2)原型对象就是一个公共区域,所有实例共享。所有对象都从原型对象、原型链中继承属性和方法。
function MyClass(){
}
MyClass.prototype.__proto__.sayName=function(){
console.log("23")
}
var s=new MyClass();
s.sayName();
3) Object.prototype 是原型链的顶端。它的原型为null
function MyClass(name){
this.name=name;
}
var s=new MyClass('hlp');
console.log(s.__proto__);
console.log(s.__proto__.__proto__);
console.log(s.__proto__.__proto__.__proto__);
4) js对象通过原型对象、原型链实现类的继承关系
function MyClass(name){
this.name=name;
}
MyClass.prototype.sayName=function(name){
console.log(this.name)
}
var s=new MyClass('hlp');
s.sayName();
var s2=new MyClass('hlp2');
s2.sayName();
1.3 原型继承验证
1)检测对象是否含有某个属性
"name" in obj;
检查对象是否含有某个属性。
如果对象中没有,就会到原型中查找。
obj.hasOwnProperty("name");
检查对象自身是否含有某个属性。
如果对象中没有,不会到原型中查找。
>>>>>> 检测对象是否含有某个属性
function MyClass(name){
this.name=name;
}
MyClass.prototype.sayName=function(name){
console.log(this.name)
}
var s=new MyClass('hlp');
console.log('sayName' in s); //true
>>>>>> 检测对象自身是否含有某个属性
hasOwnProperty检测的是对象自身是否含有某个属性。
由于sayName属性在原型对象中,所以是false。
function MyClass(name){
this.name=name;
}
MyClass.prototype.sayName=function(name){
console.log(this.name)
}
var s=new MyClass('hlp');
console.log(s.hasOwnProperty('sayName')) //false
2)原型继承验证
对象中没有hasOwnProperty方法。但是可以调用。原因是由于原型对象中。
function MyClass(name){
this.name=name;
}
var s=new MyClass('hlp');
//检测s对象中是否含有hasOwnProperty属性
console.log(s.hasOwnProperty('hasOwnProperty')); //false
//检测s对象的原型对象中是否含有hasOwnProperty属性
console.log(s.__proto__.hasOwnProperty('hasOwnProperty')); //false
//检测s对象的原型对象的原型对象中是否含有hasOwnProperty属性
console.log(s.__proto__.__proto__.hasOwnProperty('hasOwnProperty')); //true
二、构造函数优化
2.1 构造函数的缺点
每创建一个对象,就会开辟一个空间存储。
包含构造函数的方法也会开辟一个空间存储.多次存储同一个方法。浪费内存。
function Person(){
this.name="123";
this.sayName=function(){
console.log(this.name);
}
}
var p=new Person();
var p1=new Person();
console.log(p.sayName==p1.sayName); //false
2.2 构造函数的简单优化(缺点:污染全局环境)
构造函数中的函数应该提升为全局函数来存储。这样可以减小内存消耗。
【缺点:污染全局环境。】
function sayName(){
console.log(this.name);
}
function Person(){
this.name="123";
this.sayName=sayName;
}
var p=new Person();
var p1=new Person();
console.log(p.sayName==p1.sayName); //true
2.3 构造函数的深层优化
function Person(){
this.name="123";
}
Person.prototype.sayName=function(){
console.log("12")
}
var p=new Person();
var p2=new Person();
console.log(p.sayName==p2.sayName);//true
标签:console,name,--,sayName,继承,对象,原型,log 来源: https://blog.csdn.net/weixin_45602227/article/details/117902824