JavaScript 处处皆对象,没错 JavaScript 到处都是对象,那么它必须有一种机制,将所有对象分割起来。所以,Brendan Eich 最初还是设计了 ” 继承 ”。既然咱们想要理解原型和原型链,就要先理解为什么要创造原型呢?那么咱们理解了为什么创造原型,那么原型是个什么货色呢?为了解决什么问题二存在的呢?
一、原型的演变过程
<script>
/\* 在 Person 中增加了一个 sayName() 办法,\* 每执行一次函数,就创立一个 sayName() 办法,造成了内存的极大节约
\*/
function Person(name , age , gender){
this.name=name;
this.age=age;
this.gender=gender;
this.sayName=function(){alert('hello');
}
}
var per1=new Person('hbw',23,'男');
var per2=new Person('hsw',22,'男');
var per3=new Person('hew',13,'男');
/\* 能够把 sayName() 办法放在全局作用域中,共享这个办法所有的对象指的都是 sayName() 一个办法
\* 然而将函数定义在全局作用域,净化了全局作用域的命名空间
\* 而且定义在全局作用域也不平安
\*/
function Person(name , age , gender){
this.name=name;
this.age=age;
this.gender=gender;
this.sayName=sayName;
}
function sayName(){alert('hello');
}
var per1=new Person('hbw',23,'男');
var per2=new Person('hsw',22,'男');
var per3=new Person('hew',13,'男');
** 原型退场 **
###### \* 原型 prototype
\* 咱们所创立的每一个函数 (一般函数和构造函数),浏览器解析器都会向函数中增加一个属性 prototype,这个属性对应着一个对象,这个对象就是咱们所谓的原型对象
\* 如果函数作为一般函数调用 prototype 没有任何作用
\* 如果函数作为结构函数调用,它所发明的对象中都有一个隐含的属性,指向该构造函数的原型对象,所以咱们能够通过__proto__来拜访该属性
\*
\* 原型对象就相当于一块公共区域,所有同一个类的实例都能够拜访到这个原型对象
\* 咱们能够将对象中共有的内容,对立放在原型对象中,节俭了存储空间,防止了全局便量的净化
\*/
function MyClass(){}
MyClass.prototype.a=123;
console.log(MyClass.prototype);
\* 向原型中增加 sayName() 办法,不会净化命名空间,也不会占用全局作用域,而是作为构造函数的一个属性 \*/
function Person(name , age , gender){
this.name=name;
this.age=age;
this.gender=gender;
}
Person.prototype.sayName = function(){alert('hello');
}
var per1=new Person('huangbowen',23,'男');
var per2=new Person('huangshuaiwen',22,'男');
</script>
从下面演示的例子中咱们看到了构造函数,那么什么是构造函数?构造函数又是怎么运行的呢?上面咱们来说一下:
构造函数
构造函数看起来和一般函数一样,只不过函数名是大写。
那么构造函数和一般函数有什么区别呢?
1、一般函数和构造函数的区别是调用形式的不同。
一般函数是间接调用,而构造函数须要应用 new 关键字来调用。
2、构造函数的执行流程
(1)创立一个空对象 person1
(2)将 person1 的__proto__属性指向构造函数 Person 的原 prototype
(3)将新建的对象设置为构造函数中 this, 在构造函数中能够应用 this 来援用新建的对象,执行
(4)若构造函数没有返回非原始值(即不是援用类型的值),则返回该新建的对象 person1(默认会增加 return this)。否则,返回援用类型的值。
3、应用同一个构造函数创立的对象,咱们称为一类对象,也将一个构造函数称为一个类。
图片
咱们将通过一个构造函数创立的对象,称为该类的实例。