标签:
一、对象的四种创建方式
1)直接量
var Student = {name:‘小明‘,age:18};
2)通过new关键字加Object()构造函数
var student = new Object() student.id = 10; student.name = ‘王铁锤‘; student.age = 18;
缺点:使用同一个接口创建很多对象,会产生大量的重复代码.
3)封装工厂函数
为了减少重复代码,对上述代码进行封装
4)自定义构造函数
/* * 这种方式调用构造函数实际上会经历以下4个步骤: * 1> 创建一个新对象; * 2> 将构造函数的作用域赋给新对象(把this绑定到实例对象); * 3> 执行构造函数中的代码(为这个新对象添加属性); * 4> 返回新对象。 */ function Student(name, age){ this.name = name; this.age = age; this.sayName = function(){alert(this.name);}; } var s1 = new Student("王铁锤", 18);
构造函数与普通函数的唯一区别(调用方式不同):
1>任何函数,只要通过new操作符来调用,它就可以作为构造函数;
2>而任何构造函数,如果不通过new 操作符来调用,那它跟普通函数无区别。
约定:构造函数首字母大写
缺点: 构造函数方法很好用,但是存在一个浪费内存的问题。这样既不环保,也缺乏效率。
二、this关键字
this作为JS的关键字,有特殊的含义,代表了当前对象,而当前对象是谁,由函数执行时所处的环境来决定
1>用new关键字执行:this指向生成的实例对象
2>普通函数执行:this指向调用函数的对象
三、构造函数、实例、与原型对象的关系
原型对象:prototype
1> 我们创建的每个函数都有一个prototype属性,这个属性值就是原型对象
2> 原型对象默认包含一个constructor属性,指向构造函数
3> 任何写在原型对象中的属性和方法都可以让所有对象实例共享
实例:
当调用构造函数创建一个新实例后,该实例的内部将包含一个内部属性[[Prototype]],指向构造函数的原型对象。这个内部属性无法直接访问,在FF,Chrome等浏览器可以通过__proto__得到;或者通过ES5方式Object.getPrototypeOf(实例)去获取
构造函数、原型对象和实例的关系:
1>每个构造函数都有一个原型对象(prototype),
2>原型对象都包含一个指向构造函数的指针(constructor),
3>而实例都包含一个指向原型对象的内部指针([[prototype]])
判断原型和实例的关系(返回布尔值)
constructor: 得到构造函数的引用,一般用于判断该实例是否由某一构造函数生成
实例.constructor == Student //true
instanceof: 检测某个对象是不是某一构造函数的实例,适用于原型链中的所有实例
实例 instanceof Student //true
实例 instanceof Object //true
isPrototypeOf: 判断当前对象是否为实例的原型
原型对象.isPrototypeOf(实例) //true
原型链
原型链:实例与原型对象的链条
原型搜索机制扩展
最后搜索到Object构造函数
四、对象对属性的访问过程
实例对象属性的读取和写入
1)读取(原型搜索机制):
当代码读取对象的某个属性时,会先从对象实例本身开始搜索。如果在实例中找到了这个属性,则返回该属性的值;如果没有找到,则继续搜索原型对象,如果在原型对象中找到 了这个属性,则返回该属性的值
2)写入:
虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,而该属性与实例原型中的一个属性同名,该属性将会 屏蔽原型中的那个属性。(一句话:添加属性/方法只会在对象实例中添加)
3)对象属性的遍历与判断
1> for…in:遍历对象中的所有属性, 无论该属性存在于实例中还是原型中
2> in:只要通过对象能够访问到属性就返回true, 无论该属性存在于实例中还是原型中
if(name in s1){}
3>实例.hasOwnProperty(属性):检测一个属性是存在于实例中(true),还是存在于原型中(false)
4>检测一个属性是否存在于原型中:!obj.hasOwnProperty(name) && (name in obj)
五、面向对象的继承
借用构造函数
call:使用父类函数的call(子类对象,参数1,参数2,参数3......) 最常见
格式:构造函数.call(this,参数1,参数2,参数3......)
apply:使用父类函数的apply(子类对象,[参数1,参数2,参数3])
格式:父类构造函数.apply(子类当前对象,[参数1,参数2,参数3......])//第二个参数为数组
**call与apply的唯一区别:传参方式不同
**借用构造函数法只能继承构造函数里的属性/方法,不能继承原型对象里的方法
PS:借用构造函数法一般用于继承属性
原型式继承
function object(o){
function F(){}
F.prototype = o;
return new F();
}
原理:先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例
Object.create():ECMAScript 5版本的原型式继承
寄生组合继承法
继承属性:借用构造函数
继承方法:原型式继承
标签:
原文地址:http://www.cnblogs.com/hackerPJ/p/5655283.html