1.原型prototype简介
-
将函数定义在全局作用域中,污染了全局作用域的命名空间,而且定义在全局作用域中也很不安全,将函数定义了构造函数中也不太好,因为每调用一次函数,就会创造一个空间存放该函数,造成资源浪费
而原型的出现就解决了这一问题
-
我们所创建的每一个函数,解析器都会向函数添加一个叫做prototype的属性
-
而prototype这一属性对应的对象就叫做原型
-
如果函数作为普通函数调用,则prototype属性没有任何作用
-
如果函数作为构造函数调用,则构造函数创建的对象中都会有一个隐含属性,指向该构造函数的原型对象
隐含属性叫做__proto__
2.原型对象的使用
-
原型对象就相当于一个公共区域,所有同一类的实例都可以访问到这个原型对象
-
我们可以将所有实例的共有属性和方法 统一设置到原型对象中
-
当我们访问一个对象的属性时,先会在自身中寻找,如果有则直接使用,如果没有,就会去这一类对应的原型对象中寻找,如果找到则直接使用
-
以后我们创建对象时,可以将这些对象的共有属性和方法,统一添加到构造函数(类)的原型中
//构造函数
function Person(name,age){
this.name=name;
this.age=age;
}
//向Person类的原型中添加所有对象的公共方法 sayHello
Person.prototype.sayHello=function (){
console.log(this.name);
}
// console.log( Person.prototype);
//调用构造函数
var per1=new Person("孙悟空",18);
var per2=new Person("猪八戒",28);
var per3=new Person("沙和尚",38);
per1.sayHello();//先会在自身对象中找这个函数,没有就去原型对象找这个函数
per2.sayHello();
console.log( per3.proto);
3.hasOwnProperty()检查对象自身中是否含有某个属性
1.前提介绍
in运算符
通过该运算符可以判断一个对象中是否含有指定的属性,返回值是true,或false
语法:“属性名” in 对象名
2.提问
如果我们这个属性是添加在原型中的,那么对实例进行in运算结果会是怎样呢
//构造函数忽略
MyClass.prototype.name=“我是原型中的属性”
var mc=new MyClass();
console.log(“name” in mc)//返回值居然是true
这说明了使用in运算符检查对象是否包含某一属性,如果对象不包含此属性,但是原型中有,也会返回 true
3.hasOwnProperty( )方法
可以使用每个对象自带的hasOwnProperty()方法来检查对象自身中是否包含某个属性
hasOwnProperty()方法以hasOwnProperty属性存在对象中
mc.hasOwnProperty("name") //就会返回false;
mc.age=17;
mc.hasOwnProperty("age") //就会返回true
该方法只有当对象自身中含有该属性时,才会返回true
4.原型链
-
原型对象也是对象,所以它也有原型
-
当我们使用一个对象的属性或方法时,会现在自身寻找,如果自身没找到,就去对象的原型中找
如果对象的原型中没有,就去对象的原型的原型(叫做Object)中找直到找到Object对象的原型
-
Object对象的原型没有原型,如果在Object原型中都没有找到,则返回undefined
自己–>爸爸–>爷爷-(也叫Object)->Object对象原型
对象–>对象的原型–>原型对象的原型–>原型对象的原型的原型
5.toString( )方法
- 当我们直接在页面中打印一个对象时,实际上是输出被打印对象的toString( )方法的返回值
- toString()方法不直接存在在对象中,而是直接存在于Object对象中
- 如果我们希望在输出对象时,不输出【Object object】那么可以为输出对象添加一个toString( )方法,自己有了此方法,就不会向上级原型寻找了
- 我们可以修改原型的toString( )方法,来实现对所有对象的输出
6.垃圾回收机制
- 不再使用的对象的内存将会自动回收,这种功能称作垃圾回收。
• 所谓不再使用的对象,指的是没有被任何 一个属性(变量)引用的对象。
• 垃圾回收的目的是,使开发者不必为对象 的生命周期管理花费太多精力
- 我们只需要把不用的对象设置null,对象即可自动被回收