定义:

原型是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

返回构造对象的构造函数:

javascript原型原型链 javascript原型和原型链_javascript原型原型链

原型链

  • 绝大多数对象的最终都会继承自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

[特性]

  1. 函数预编译过程this—>window
  2. 全局作用域里的this---->window
  3. call/apply可以改变函数运行时this指向
  4. obj.func();func()里面的this指向obj