ECMAScript有两种开发模式:
n 面向过程--函数式(过程化).
n 面向对象(OOP)。面向对象的语言有一个标志,那就是类(构造函数)的概念,而通过类可以创建任意多个具有相同属性和方法的实例对象。但是,ECMAScript没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。(基于面向对象)
面向对象的特点(了解)
n 抽象:就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。
n 封装:就是把我们抽象出的属性和对属性的操作写到类的定义中,称为封装.只能通过对象来访问。
n 继承:从已有的对象上,继承出新的对象。
n 多态:多态性是指允许不同类的对象对同一消息作出响应。
对象的组成
n 属性(对象下)--变量(自由的):状态、静态的。
n 方法(对象下)--函数(自由的):过程、动态的。
使用Json创建对象(obj={}字面量创建)
使用构造函数创建对象(object)
工厂模式
工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。
工厂模式的实现方法非常简单,通过封装解决了创建多个相似对象的问题,但是却无从 识别对象的类型,因为全部都是Object,不像Date、Array等
/2、工厂模式
/*function createPerson(name,age,worker){
//原材料
var obj=new Object();
obj.name=name;
obj.age=age;
obj.worker=worker;
//加工
obj.showInfo=function(){
alert('他的名字是:'+obj.name+',他今年'+obj.age+'岁,他目前是'+obj.worker);
};
//出厂
return obj;
}
var p1=createPerson('zhangsan',30,'student');
//p1.showInfo();
var p2=createPerson('lisi',20,'teacher');
//p2.showInfo();
var p3=createPerson('wangwu',50,'star');
//p3.showInfo();
alert(p1.showInfo==p2.showInfo);//false;*/
//工程模式问题:无法区分对象的类别
//3、构造函数:首字母大写,new创建
//以 new 操作符调用构造函数的时候,函数内部发生以下变化:
//1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
//2、属性和方法被加入到 this 引用的对象中。
//3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
function CreatePerson(name,age,worker){
//构造函数里面的this指向实例
//var this=new Object();//系统已经创建了,隐式创建
this.name=name;
this.age=age;
this.worker=worker;
this.showInfo=function(){
alert('他的名字是:'+this.name+',他今年'+this.age+'岁,他目前是'+this.worker);
};
//return this;//隐式返回
}
var p1=new CreatePerson('zhangsan',30,'student');
p1.showInfo();
var p2=new CreatePerson('lisi',20,'teacher');
p2.showInfo();
var p3=new CreatePerson('wangwu',50,'star');
p3.showInfo();
alert(p1.showInfo==p2.showInfo);//false
//总结:p1,p2,p3实例对象 CreatePerson:构造函数(类)
构造函数的使用
创建自定义的构造函数意味着将来可以将他的实例标识为一种特定的类型,这就是构造 函数比工厂模式强的地方,因为它知道自己从哪里来,通过谁产生的。
n 构造函数:其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例对象,并且this变量会绑定在实例对象上。
n 构造函数的基本特点:首字母大写 new运算符创建。
n 构造函数模式虽然好用,但也并非没有缺点。使用构造函数的主要问题,就是每个方法都要在每个实例对象上重新创建一遍。
new的使用
以 new 操作符调用构造函数的时候,函数内部发生以下变化:
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
Prototype(原型)--原型的概念
Javascript规定,每一个函数都有一个prototype对象属性,指向另一个对象(原型链)。
prototype对象属性的所有属性和方法,都会被构造函数的实例继承。这意味着,我们可以把 那些不变(公用)的属性和方法,直接定义在prototype对象属性上。
n prototype就是调用构造函数创建的那个实例对象的原型(__proto__)。
n prototype可以让所有对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
n 构造函数与实例
构造函数(类)---不具备方法和属性,只能用来构造实例对象,构造函数里面添加的 是属性(因为一般情况下属性各不相同)原型里面添加的是方法(因为方法都一样)
实例(实例对象),具有一定的功能,被构造函数(类)构造出来的。
Prototype模式的其他验证方法
n hasOwnProperty() : 看是不是对象自身下面的属性, 只在属性存在于实例中时才返回 true。
n in操作符用来判断某个属性属于某个实例对象,可以是对象的直接属性,也可以是通过prototype继承的属性(包括Object下面的属性)。
n toString() :系统对象下面都是自带的 , 自己写的对象都是通过原型链找Object下面的,可以把对象转成字符串, 可以做进制转换或者类型的判断。
n constructor:实例对象的构造函数
n instanceof:判断一个对象是否是一个构造函数(类)的实例。
JS原型与原型链
实例对象与原型之间的连接,叫做原型链。__proto__( 隐式连接 )
JS在创建对象的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype。
内部原型(__proto__)和构造器的原型(prototype)
1、每个对象都有一个__proto__属性,原型链上的对象正是依靠这个属性连结在一起
2、作为一个对象,当你访问其中的一个属性或方法的时候,如果这个对象中没有这个方法或属性,那么Javascript引擎将会访问这个对象的__proto__属性所指向上一个对象,并在那个对象中查找指定的方法或属性,如果不能找到,那就会继续通过那个对象的__proto__属性指向的对象进行向上查找,直到这个链表结束。
原型链的最外层:object.prototype
变量作用域(全局作用域、局部作用域)
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量,在函数外部自然无法读取 函数内的局部变量。
什么是闭包(闭包的原理)
闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函 数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质 上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的特点
闭包特性1: 函数内部的函数所引用的变量 会被保存下来
闭包特性2: 由于内部函数所引用的外部变量会被保存下来 所以变量会一直在内存中保存直到 浏览器被关闭,垃圾回收机制失效
闭包的应用场景
n 局部变量的累加
n 自执行的匿名函数保存循环变量
使用闭包的注意点
1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包, 否则会造成网页的性能问题,在IE中可能导致内存泄露。
2、闭包会在父函数外部,改变父函数内部变量的值。
构造函数继承
将父对象的构造函数绑定在子对象上。
call/apply继承
在子对象构造函数中利用call或apply将父对象指向子对象的实例对象。
Prototype(原型)--原型的概念
Javascript规定,每一个函数都有一个prototype对象属性,指向另一个对象(原型链)。
prototype对象属性的所有属性和方法,都会被构造函数的实例继承。这意味着,我们可以把 那些不变(公用)的属性和方法,直接定义在prototype对象属性上。
n prototype就是调用构造函数创建的那个实例对象的原型(__proto__)。
n prototype可以让所有对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
n 构造函数与实例
构造函数(类)---不具备方法和属性,只能用来构造实例对象,构造函数里面添加的 是属性(因为一般情况下属性各不相同)原型里面添加的是方法(因为方法都一样)
实例(实例对象),具有一定的功能,被构造函数(类)构造出来的。
Prototype模式的其他验证方法
n hasOwnProperty() : 看是不是对象自身下面的属性, 只在属性存在于实例中时才返回 true。
p1.hasOwnProperty('name')
n in操作符用来判断某个属性属于某个实例对象,可以是对象的直接属性,也可以是通过prototype继承的属性(包括Object下面的属性)。
n alert('name' in p1);//true
n toString() :系统对象下面都是自带的 , 系统对象都有toString(),自己写的对象都是通过原型链找Object下面的,可以把对象转成字符串, 可以做进制转换或者类型的判断
alert(Object.prototype.toString.call(10));//[object number]
alert(Object.prototype.toString.call('abc'));//[object sring]
alert(Object.prototype.toString.call([]));
alert(Object.prototype.toString.call({}));
alert(Object.prototype.toString.call(function(){}));
alert(Object.prototype.toString.call(true));
alert(Object.prototype.toString.call(new Date));
alert(Object.prototype.toString.call(new RegExp));
alert(Object.prototype.toString.call(null));
alert(Object.prototype.toString.call(undefined));。
n constructor:实例对象的构造函数 (实例对象.constructor)
var p1=new CreatePerson('zhangsan');//实例new出来的
n alert(p1.constructor);//function CreatePerson(){}
n var p1=createPerson('zhangsan');
n alert(p1.constructor);//function Object(){}
n instanceof:判断一个对象是否是一个构造函数(类)的实例。
n alert(p1 instanceof Person)
n isPrototypeOf (): 判断一个实例对象是否指向了该构造函数的原型对象。
Person.prototype.isPrototypeOf(p2)
原型链继承(JS原型与原型链)
实例对象与原型之间的连接,叫做原型链。__proto__( 隐式连接 )
JS在创建对象的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype。
内部原型(__proto__)和构造器的原型(prototype)
1、每个对象都有一个__proto__属性,原型链上的对象正是依靠这个属性连结在一起
2、作为一个对象,当你访问其中的一个属性或方法的时候,如果这个对象中没有这个方法或属性,那么Javascript引擎将会访问这个对象的__proto__属性所指向上一个对象,并在那个对象中查找指定的方法或属性,如果不能找到,那就会继续通过那个对象的__proto__属性指向的对象进行向上查找,直到这个链表结束。
原型链的最外层:object.prototype-->null
混合继承(构造函数+原型混合方式实现js的继承)
arguments是一个类似数组(但不是数组)的对象,用于保存函数的参数,即使函数定义时没有定义参数,arguments也会保存实际调用时使用的参数
· 封装——把相关的信息(无论数据或方法)存储在对象中的能力。
· 聚集——把一个对象存储在另一个对象内的能力。
· 继承——由另一个类(或多个类)得来类的属性和方法的能力。
· 多态——编写能以多种方法运行的函数或方法的能力。