定义:
原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象
利用原型特点和概念,可以提取共有属性
//Car.prototype --指的就是 Car的原型对象
//Car.prototype = {} 祖先
Car.prototype={
height : 1400,
lang : 4900,
carName : "BMW"
}//提取3个共有属性
function Car(color,owner){
this.owner = owner;
this.color = color;
}
var car = new Car('red','wang');//继承祖先属性,也可以调用car.carName及其他属性
var car1 = new Car('green','song');//继承祖先属性,也可以调用car1.carName及其他属性
//补充说明,若Car()函数内有carName属性,car.carName则输出函数内的值,不会去继承祖先的(类似就近原则);
//构造函数无法对祖先的属性进行修改
对象如何查看原型的隐式属性:__proto__
Person.prototype.name = 'sunny';
function Person(){
//var this = {__proto__: Person.prototype}
}
var person = new Person(); //new一个对象出来就会生成自己的prototype
//Person.prototype.name = 'cherry'//这样写输出person.name就是'cherry'
Person.prototype = {//此时是又构造了一个新的prototype,不同与上一个prototype
name : 'cherry'
}
person.name//输出'sunny'
Person.prototype.name = 'sunny';
function Person(){
//var this = {__proto__: Person.prototype}
}
Person.prototype = {//此时是又构造了一个新的prototype,不同与上一个prototype
name : 'cherry'
}
var person = new Person(); //new一个对象出来就会生成自己的prototype,继承name : 'cherry'的prototype
person.name//输出'cherry'
对象如何查看对象的构造函数:constructor
返回构造对象的构造函数:
原型链
- 绝大多数对象的最终都会继承自
Object.prototype
特例:var obj = Object.create(原型,特性) 括号内必须填对象的原型
var demo = {
lastName : "abc"
}
var obj = Object.create(demo)
obj = {
__proto__:demo
}
Student.prototype = Object.create(Person.prototype);//相当于复制了一份Person.prototype
Student.prototype.constructor = Student;//重置Student.prototype.contructor的指向,原先指向Person
- Object.create示例:
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log("eat!")
}
console.log("Person")
console.dir(Person.prototype)
function Student(name,age){
Person.call(this,name,age);
this.payMoney = function (){
console.log("payMoney!")
}
}
Student.prototype = Object.create(Person.prototype);//相当于复制了一份Person.prototype
Student.prototype.constructor = Student;//重置Student.prototype.contructor的指向,原先指向Person
Student.prototype.study = function (){//此句写前会被new Person("xiaoming",18);覆盖
console.log("study!")
}
console.log("Student")
console.dir(Student.prototype)
function LitStudent(name,age){
Student.call(this,name,age)
this.cry = function(){
console.log("cry!")
}
}
LitStudent.prototype = Object.create(Student.prototype);
LitStudent.prototype.contructor = LitStudent;
let Pupil = new LitStudent("xiaoming",18);
function xiaoming(){
console.log(Pupil.name);
console.log(Pupil.age);
Pupil.study();
Pupil.cry();
Pupil.payMoney();
Pupil.eat();
}
xiaoming()
let daming = new Student("daming",20);
function DM(){
console.log(daming.name);
console.log(daming.age);
daming.study();
daming.payMoney();
daming.eat();
// daming.cry();//此处无法调用cry方法,因为Student没有该方法
}
DM()
- 属性知识点补充
一旦经历了var
操作,所得出的属性,window,这种属性叫做不可配置的属性,不可配置属性delete不掉
(function(x){//形参x,相当于var x;
//var x;
delete x;//无法删除
return x;
})(1);//1
call/apply
- 功能:改变
this
指向
test.call()—括号里的值去调用test函数
var name = "window";
var obj = {
name:"obj",
say:function(){
console.log(this.name);
}
}
obj.say.call(window)//"window" .call会改变this指向,此时的this是window
var fn = obj.say;
fn();//此时打印出来的是"window" 预编译this指向window
fn().call(obj);//obj
//利用call可以改变this指向,去调用公共属性
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,tel,grade){
Person.call(this,name,age,sex);//调用Person方法,第一个值是指Student调用,后面的传值是实参对应Person方法的形参
this.tel = tel;
this.grade = grade;
}
var student = new Student('sunny',123,'male',139,2017);
- 区别:后面传的参数形式不同
- [call] 需要把实参按照形参的个数传值
- [apply] 需要传一个arguments(数组)
apply
Person.apply(this,[name,age,sex]);
this
[特性]
- 函数预编译过程this—>window
- 全局作用域里的this---->window
- call/apply可以改变函数运行时this指向
- obj.func();func()里面的this指向obj