JavaScript原型

来源:互联网 发布:ios 元数据丢失 编辑:程序博客网 时间:2024/05/16 17:43
JavaScript原型
js 的对象比较
由于js是解释执行的语言,那么在代码中出现函数与对象如果重复执行,就会创建对个副本
1. 在代码中重复执行的代码容易出现重复的对象
2. 创建一个Person 构造函数,以创建对象,要求有name、age、gender 和sayHellow

/*
function Person ( name , age , gender ){
this.name = name ;
this.age = age ;
this.gender =gender ;
this.sayHellow = function(){
console.log("Hello word ");
}
}
var p1 = new Preson('wxj',11,'ceshi');

*/

3. 传统的构造方法的定义会影响性能,容易造成对个对象有对个对象副本,应该将方法单独抽取出来,让所有的对象共享该方法
4. 可以考虑将方法全部放到外面,但是会有安全隐患
* 在开发中会引入各种框架或库,自定义的成员越多,出现命名冲突的几率越大
* 可能在开发中会有多个构造函数,每一个构造函数应该有多个方法,那么就会变得不容易维护
5. 任意一个对象 都会默认的链接到原型中
* 创建一个函数,会附带的创建一个特殊的对象,这个对象会使用函数 .prototype 引用。称其为函数数的原型属性
例子:
var o = {};
o = null;
* 每一个由该函数作为构造函数创建得到对象,都会默认的链接到该对象上。
* 在该对象访问某一个方法或者属性的时候,如果该对象中没有,就会到这个神秘的对象中查找。

## 传统构造函数的问题
``````
function Foo(){
this.sayHello = function(){}
}
``````
1. 由于对象是调用 `new Foo()` 所创建出来的,因此每一个对象在创建的时候,函数sayHello都会被创建一次
2. 那么每一个对象都含有一个独立的、不同的,但是功能逻辑一样的函数。比如:`{}` == `{}`
3. 在代码中方法会消耗性能,最典型的资源就是内存。
4. 这李最好的方法是将函数体放在构造函数之外,那么在构造函数中只需要引用该函数即可
`````
function sayHello (){}
function Foo(){
this.say = sayHello ;
}
`````
5. 会在开发中变得困难:引入框架危险,代码繁冗不好维护,解决方法就是外面的函数如果不占用名字,而且在函数旗下就好。
6. 每一个函数在定义的时候,有一个神秘对象被创建出来。
7. 每一个由构造函数创建的对象都会默认的链接该神秘对象上。
`````
var f1 = new Foo();
var f2 = new Foo();
f1.sayHello(); //如果f1没有sayHello,那么就会在 Foo.prototype 中找
f2.sayGoodBye(); //如果f2没有sayHello,那么就会在 Foo.prototype 中找
`````
8. 由构造函数创建出来的众多对象共享一个对象,就是构造函数 .prototype
9. 只需要将共享的东西,重复会占用多内存的东西放到 .prototype 中,那么所有的对象就可以共享了
``````
//优化后的构造函数
function Foo(){}
Foo.prototype.sayHello = function(){
console.log('---------');
}

var f1 = new Foo();
f1.sayHello();
var f2 = new Foo();
f2.sayHello();

f1.sayHello() === f2.sayHello(); true

``````

### 常见错误
1. 写构造函数.prototype 的时候,将属性加到里面
```
function Person(){}
Person.prototype.name = '张三';
var p = new Person();
```
2. 复制的错误
```
function Person(){}
Person.prototype.name = '张三';
var p1 = new Person();
var p2 = new Person();
p1.name = '李四';
console.log(p1.name);
console.log(p2.name);
//如果是访问数据,当前对象如果没有该数据就到构造函数的原型属性中找
//如果是写数据,当对象中有该数据的时候,就是修改值;如果对象没有该数据,那么就是添加值

```
## 原型相关的概念
1. 关于面向对象的概念
* 类 class : 在 js 中就是构造函数
*在传统的面向对象语言中,使用一个叫做类的东西定义模板,然后使用模板创建对象。
*在构造方法中也具有类似的功能,因此称其为类
````
//在java中,最小的代码单位是类
class Program{
//成员
}
````
* 实例(instance) 与对象(object)
*实例一般是指某一个构造函数创建出来的对象,我们成为XXX 构造函数的实例
*实例就是对象,对象是一个泛称
*实例与对象是一个近义词

*键值与属性和方法
*在js中简直对的集合称之为对象
*如果值为数据(非函数) ,就称该键值对为属性 prototype
*如果值为函数(function),就称该键值对为方法 method
*父类与子类
*传统的面向对象语言中使用类来实现继承,那么就有父类,子类的概念
*父类又称为基类,子类又称为派生类
*在JS中常常成为父对象,子对象,基对象,派生类

2. 原型相关的概念
* 神秘对象针对构造函数称其为“原型属性”
* 神秘对象就是构造函数的原型属性
* 简称原型
* 神秘对象与构造函数所创建出来的对象也有一定关系
*关系是什么
*神秘对象针对构造函数创建出来的对象成为原型对象
*简称原型
*对象继承其自原型
*构造函数创建的对象 继承 自 构造函数的原型属性
*构造函数创建的对象 继承 自 该对象的原型对象
*构造函数所创建出来的对象与构造函数的原型属性表示的对象是两个不同的对象
*原型中的成员, 可以直接被实例对象所使用
*也就是说实例对象直接 “含有” 原型中的成员
*因此实例对象 继承 自 原型
*这样的继承就是 “原型继承”

原创粉丝点击