一、原型对象
测试题1:判断以下四个函数调用分别打印什么?
<script>
// 测试题1:判断以下四个函数调用分别打印什么?
var F = function () {}
Object.prototype.a = function () {
console.log('a')
}
Function.prototype.b = function () {
console.log('b')
}
var f = new F();
f.a();
f.b();
F.a();
F.b();
</script>
<script>
// 测试题1:判断以下四个函数调用分别打印什么?
var F = function () {}
Object.prototype.a = function () {
console.log('a')
}
Function.prototype.b = function () {
console.log('b')
}
var f = new F();
f.a(); //'a'
// f.b(); //报错 f.b is not a function
// f是构造函数F的实例化对象
// f.__proto__==F.prototype;
// F.prototype.__proto__==Object.protype;
// Object.protype.__proto__==null;
// f.__proto__.__proto__.__proto__=null;
F.a(); //'a'
F.b(); //'b'
// F.__proto__==Function.prototype;
// Function.prototype.__proto__==Object.prototype;
// Object.prototype.__proto__==null;
// F.__proto__.__proto__.__proto__=null;
</script>
1.什么是原型?
在js中,每一个函数类型的数据,都有一个叫做 prototype的属性,这个属性指向的是一个对象,就是所谓的原型对象,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象(实例化对象),可以继承该原型的属性和方法。原型对象有个constructor属性,指向它的构造函数。
注意:原型对象也是对象
【1】显示原型
显示原型就是利用prototype属性查找原型,只是这个是函数类型数据的属性。
隐式原型是利用__proto__属性查找原型,这个属性指向当前对象的构造函数的原型对象,这个属性是对象类型数据的属性,所以可以在实例对象上面使用
2.什么是构造函数?
构造函数和普通函数本质上没什么区别,构造函数是使用了new关键字的函数,用来创建对象(实例化对象);构造函数的首字母一般是大写,用以区分普通函数。
在js中,对象的构造函数就是Object(),所以对象的原型对象,就是Object.prototype,并且Object.prototype.__proto__==null
3.注意
【1】所有的原型对象都是由Object函数对象创建的
【2】Function函数对象由自己Function,Function.__proto__ == Function.prototype
【3】所有的函数都是由Function函数对象创建
【4】构造函数创建的对象,对象的__proto__指向构造函数的prototype
【5】不是构造函数创建的对象,对象的__proto__指向Object函数对象的prototype
【6】对象访问某个属性,如果自己身上有这个属性,优先访问自己的;如果没有再访问原型链上的,沿着原型链依次往上层链找,如果还没有就返回Undefined
<script>
// 1.所有的原型对象都是由Object函数对象创建的
console.log(Function.prototype.__proto__==Object.prototype);
// 2.Function函数对象由自己Function
console.log(Function.__proto__ == Function.prototype)
// 3.所有的函数都是由Function函数对象创建
console.log(F.__proto__==Function.prototype);
// 4.构造函数创建的对象,对象的__proto__指向构造函数的prototype
console.log(f.__proto__==F.prototype);
// 5.不是构造函数创建的对象,对象的__proto__指向Object函数对象的prototype
var obj={"name":"cll"}
console.log(obj.__proto__==Object.prototype);
// 6.对象访问某个属性,如果自己身上有这个属性,优先访问自己的;如果没有再访问原型链上的,沿着原型链依次往上层链找,如果还没有就返回Undefined
var newStr=new String("");
newStr.toString=function(){
alert("自己的toString 方法")
}
newStr.toString(); // 弹框显示"自己的toString 方法"
</script>
二、原型的使用
1.原型上追加属性或方法,让所有实例化对象得到继承
<script src="">
//作用一:在原型上追加属性或方法,让所有实例化对象得到继承
var p1 = {
name: "水杯",
price: 100
},
p2 = {
name: "话筒",
price: 1000,
zhekou: 0.8
}
Object.prototype.getLength = function() {
var sum = 0;
for (var x in this) {
if (x == "getLength") continue;
sum++;
}
return sum;
}
console.log(p1.getLength());
</script>
2.原型 提取公有属性、公共方法
<script src="">
//作用二、原型 提取公有属性、公共方法
// 【3】节省代码把相同属性提取出来写作写在一起
Cat.prototype.type = "中华田园猫!";
Cat.prototype.color = "黄白相见";
Cat.prototype.sayHello = function() {
console.log("喵~");
}
// 【1】构造一个Cat函数
function Cat(name, age, price) { //猫有名字,年龄,价格
// 定义猫的品种和颜色
// this.type="中华田园猫!"
// this.color="黄白相见"
// 传值
this.name = name;
this.age = age;
this.price = price;
// this.sayHello=function(){ //猫有行为
// console.log("喵~");
// }
}
// 【2】创建实例化对象
var cat1 = new Cat("小明", 2, 1000),
cat2 = new Cat("小可", 1, 2000);
// cat1 和cat2 都有相同的属性
console.log(cat1);
console.log(cat2);
console.log(cat1.sayHello == cat2.sayHello); //false
</script>
3.构造原型链实现继承
<script src="">
// 作用3:构造原型链实现继承
// 【2】在grandpa上写一个方法
GranPa.prototype.g1 = 100000000;
// 【1】构造函数
function GranPa(name, address) {
this.name = name;
this.address = address;
}
var grand1 = new GranPa("爷爷", "广东");
Father.prototype=GranPa.prototype; //【3】继承 写法1:会造成感染的也会有father的属性money
Father.prototype = new GranPa(); //【3】继承 写法2就不会有写法1 的情况
Father.prototype.money = "全国各地各大豪宅!"
function Father(name, address) {
this.name = name;
this.address = address;
}
var f1 = new Father("爸爸", "深圳");
Son.prototype = new Father();
function Son(name, address) {
this.name = name;
this.address = address;
}
var s1 = new Son("孙子", "四川")
</script>