7

JS 对象创建的三种方式

//字面量创建方式
var person= { name:'jack' }

//系统内置构造函数方式
var person= new Object();
person.name = 'jack';

//自定义构造函数
function Person(name){
    this.name = name;
}
var person = new Person('jack');

JS 构造函数、原型、实例之间的关系

  实例是由构造函数实例化创建的,每个函数在被创建的时候,都会默认有一个prototype对象。该对象就是构造函数的原型,并且原型对象中还有一个constructor属性,指向的是原型所在的构造函数。

  • 在每一个实例对象中的__proto__中同时有一个 constructor 属性,该属性指向创建该实例的构造函数。
  • 构造函数的 prototype对象默认都有一个 constructor 属性,指向 prototype 对象所在函数。

关系图

(图片原址:https://www.oecom.cn/the-rela...


值类型成员或者引用类型成员写入(实例对象.成员 = xx):

  • 当实例期望重写原型对象中的某个普通数据成员时实际上会把该成员添加到自己身上,
  • 也就是说该行为实际上会屏蔽掉对原型对象成员的访问

复杂类型修改(实例对象.成员.xx = xx):

  • 同样会先在自己身上找该成员,如果自己身上找到则直接修改,
  • 如果自己身上找不到,则沿着原型链继续查找,如果找到则修改,
  • 如果一直到原型链的末端还没有找到该成员,则报错(实例对象.undefined.xx = xx)。

JS 构造函数常用用法

function Person( name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
}

Person.prototype = {
    constructor:Person, //修正,指向正确的构造函数
    introduce:function(){
        console.log('hello,everybody. my name is'+ this.name +'\n')
    }
}  
  • 不需要共享的数据写在构造函数中,需要共享的数据写在原型中。
  • 实例对象使用的属性或者方法,先在实例中查找,找到了则直接使用,找不到则,去实例对象的__proto__指向的原型对象prototype中找,找到了则使用,找不到则报错。
  • 原型链:是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的

JS 封装、继承、多态

  面向对象的编程语言中有类的概念,而JS是基于对象的语言,JS中没有类,但是JS可以模拟面向对象的思想编程,JS通过构造函数模拟类的概念。

封装:一系列属性放在对象中或者一系列实现某种功能的方法放在对象,就是封装。
继承:继承属于类与类之间的关系,JS通过构造函数模拟类,通过原型来实现继承,继承的目的是为了实现数据共享。
多态:一个对象有不同的行为,或者同一个行为针对不同的对象,产生不同的结果,要想有多态,就要先有继承,JS中可以模拟多态。

JS 继承方式

借用构造函数继承:构造函数的名字.call( 当前对象,属性,属性....)

  • 解决了属性继承问题,但是不能继承父级的方法。  
function Person(name,age){
    this.name = name;
    this.age = age;
}

function Student(name,age,score) {
    Person.call(this,name,age);
    this.score = score;
}

var Ming = new Student('小明','18','100');

组合继承:原型继承 + 借用构造函数继承 

function Person(name,age){
    this.name = name;
    this.age = age;
}

Person.prototype.introduce = function(){
    console.log('hello,everybody,my name is ' + this.name);
}

function Student(name,age,score) {
    Person.call(this,name,age);
    this.score = score;
}

Student.prototype = new Person();
var Ming = new Student('小明','18','100');

寄生组合继承:寄生式继承 + 借用构造函数继承 

function inheritObject(o){
    function F(){};
    F.prototype = o;
    return new F();
}
function inheritPrototype(subclass,superclass){
    var p = inheritObject(superclass.prototype);
    p.constructor = subclass;
    subclass.prototype = p;
}

//定义父类
function SuperClass(name){
    this.name = name;
    this.colors = [red,blue]
}
SuperClass.prototype.getName = function(){
    console.log(this.name);
}    
//定义子类
function SubClass(name,time){
    //构造函数式继承
    SuperClass.call(this,name);
    this.time = time;
}
//寄生式继承父类原型
inheritPrototype(SubClass,SuperClass);
//子类新增原型方法
SubClass.prototype.getTime = function(){
    console.log(this.time);
}

模拟多继承: 

Object.prototype.mix = function(){
    var i = 0,                //从第一个参数起为被继承对象
        len = arguments.length,   //获取参数长度
        arg;                  //缓存参数对象
    for(;i < len; i++){
        //缓存当前对象
        arg = arguments[i];
        for(var property in arg){
            this[property] = arg[property];
        }
    }
}

attacki
35 声望2 粉丝