js学习笔记二

来源:互联网 发布:迈克尔法斯宾德 知乎 编辑:程序博客网 时间:2024/05/24 01:43

1.      oop

(1)      ESMAScript有两种属性:数据属性和访问器属性。可以通过:

Object.defineProperty() 来修改。

(2)      属性前面加一下划线,表示能通过对象方法访问该属性。

(3)      按照惯例,构造函数的函数名是以一个大写字母开头。非构造函数则以一个小写字母开头。

 

2.      工厂模式

function createPerson(name, age, job){        var o = new Object();        o.name = name;        o.age = age;        o.job = job;        o.sayName = function(){            alert(this.name);        };        return o;                           //return    }var Person1 = createPerson("Nicholes", 29,"Engineer");

3.      构造函数模式

function Person(name, age, job){        this.name = name;        this.age = age;        this.job =job;        this.sayName = function(){            alert(this.name);        };    }    var person1 = newPerson("Nicholes", 29, "Engineer");  //此时它是构造函数模式    Person("Greg", 23, "Doctor");  


 //当作普通函数使用  添加到Window 应为this 指向Windows

    window.sayName();        //"Greg"    var o = new Object();              //在另一个对象作用域中调用    Person.call(o, "Kiven", 23,"Nursr");    o.sayName();

4.      原型模式

 function Person(){}    Person.prototype.name = "Greg";    Person.prototype.age = 34;    Person.prototype.job = "Doctor";    Person.prototype.sayName = function(){        alert(this.name);    };    var person1 = new Person();    var person2 = new Person();

//所有实例共享这些属性和方法。

 

说明:只要创建一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象(Person prototype),所有的原型对象都会自动获得一个constructor属性,Person. prototype.constructor 指向了Person

              person1. constructor== Person

             Person. prototype.constructor==Person

             Object.getPrototypeOf(person1)== Person.prototype

(2) 虽然可以通过对象实例访问访问保存在原型中的值,但是不能通过对象的实例来改变原型中的属性(它只是在该对象实例中覆盖了原型中的属性,但是属性的值是可以改变的),不过使用delete可以删除新定义的这个实例属性,从而能让我访问原型属性。

(3)hasOwnProperty()可以检测一个属性是属于实例属性(返回true)还是属于原型属性,

        alert(person1.hasOwnProperty(“nane”));

(4)in可以单独使用。

   alert(“name” in person1);  //只要在person1中能访问到name属性就返回true

5.      更简单的原型语法

function Person(){}    Person.prototype = {      //属性名也可以是字符串 “name”        name : "Greg",        age : 34,        job : "Doctor",        sayName : function(){            alert(this.name);        }};var person1 = new Person();

但是此时实例对象的constructor属性不再指向Person

person1. constructor == Person  //false

 

6.      我们可以使用Person.prototype.sayHi = function(){}  给原型对象添加属性,并且所有之前或之后实例化的对象都可使用新增的属性(应为这些实例只是一个指针,指向原型),但是如果使用构造函数重写,那么构造函数之前的实例,就不能指向新的对象原型。

 

7.      组合使用构造函数模式和原型模式。(创建自定义类型的最常见方式。)

 

(1)      构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。

(2)      包含引用类型值的原型属性会被所有实例共享,而这也是为什么要在构造函数中,而不是在原型对象中定义属性的原因。                 

 

8.      ECMASeript只支持实现继承,而且实现继承主要是依靠原型链来实现的。

function Super(){        this.property = true;    }    Super.prototype.getSuper = function(){        return this.property;    };     function Sub(){        this.subproperty = false;    }    Sub.prototype = new Super();   //继承了Super  给它替换原型    Sub.prototype.getSub = function(){        return this.subproperty;    };     var instance = new  Sub();    alert(instance.getSuper());    //true    alert(instance.getSub());       //false    alert(instance.property);       //true    var instance2 = new Super();alert(instance2.getSub());           //报错<span style="font-size:18px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>

说明:(1)给原型添加方法的代码一定要放在替换原型语句之后。

(2)在通过原型链实现继承时,不能使用对象字面量创建原型的方法,否则会重写原型链。

(3)若被继承者存在引用类型  则会被继承者的所有实例共享属性(问题)

(4)不能向超类构造函数中传递参数。

 

9.      继承  (借用构造函数 有时也叫伪造对象或者经典继承  可以解决 原型中包含引用类型值所带来问题)

function Super(name){        this.name = name;    }    function Sub(){        Super.call(this,"Greg");  //借用超类的构造函数,同时可以向超类传递参数        this.age = 29;              //实例属性    }     var instance = new Sub();    alert(instance.name);   //"Greg"alert(instance.age);     //29

说明:为了确保超类的构造函数不会重写子类的实例属性,可以在调用超类构造函数之后,再添加子类中的实例属性。

 

10.  组合继承——最常用的继承模式(有时也叫伪经典继承,是将原型链和构造函数技术组合在一起)

使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。

function Super(name){        this.name = name;        this.colors = ["red","green", "black"];    }    Super.prototype.sayName = function(){        alert(this.name);    };     function Sub(name, age){        Super.call(this, name);       //继承属性        this.age = age;               //添加子类属性    }    //继承方法    Sub.prototype = new Super();    Sub.prototype.constructor = Sub;    Sub.prototype.sayAge = function(){    //添加子类方法        alert(this.age);    };      var instance1 = new Sub("Greg",24);   instance1.colors.push("yellow");  //将不会被其他实例共享   其他实例还是上面三种颜色    instance1.sayAge();     //24    instance1.sayName();  //"Greg"

11.   寄生组合式继承   是引用类型最理想的继承范式

function inheritPrototype(subType, superType){        var prototype =Object(superType.prototype);   //创建对象        prototype.constructor = subType;                //增强对象        subType.prototype = prototype;                  //指定对象    }    function Super(name){        this.name = name;        this.colors = ["red","green", "black"];    }    Super.prototype.sayName = function(){        alert(this.name);    };     function Sub(name, age){        Super.call(this, name);       //继承属性        this.age = age;               //添加子类属性    }   inheritPrototype(Sub, Super);    Sub.prototype.sayAge = function(){    //添加子类方法        alert(this.age);    };      var instance1 = new Sub("Greg",24);   instance1.colors.push("yellow");  //将不会被其他实例共享   其他实例还是上面三种颜色    alert(instance1.colors);    instance1.sayAge();     //24    instance1.sayName(); //"Greg"


 

使用这种方式只调用一次父类。

0 0
原创粉丝点击