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"
使用这种方式只调用一次父类。
- JS学习笔记二
- js学习笔记二
- JS学习笔记(二)
- js 学习笔记(二)
- Angular.js学习笔记(二)
- js学习笔记(二)
- js学习笔记(二)
- angular.js学习笔记(二)
- Vue.js学习笔记(二)
- JS学习笔记(二)
- JS学习笔记(二)
- 视频学习js笔记(二)
- js 操作HtmlDom 学习笔记二
- JavaScript学习笔记(二)JS对象
- cocos2d-js学习笔记<二> 创建工程
- augular.js 菜鸟学习笔记 (二)
- 学习笔记-JS公开课二
- JS面向对象学习笔记(二)
- CF感悟
- web.xml配置详解
- Android开发工具类大集合(八)
- 深圳外贸电子烟行业如何使用paypal来收款,有什么需要注意的地方呢?
- sqoop的安装和使用
- js学习笔记二
- qemu 网络通信
- 9.JavaWeb基础 FileUpload
- 【数据结构——跳表】跳表
- 原码反码补码基础
- Cocos2d-x 中遇到的一些问题解决办法
- 要学会写小程序来完成自己想要的功能
- php5.4.31安装php_fileinfo扩展和php_intl扩展
- tornado的ui_mothod