Javascript对象创建
来源:互联网 发布:angularroute.js下载 编辑:程序博客网 时间:2024/04/29 03:48
本文参考张龙老师和Java1234视频教程
方法的定义
function fn1(name){ alert(name+"1");}function fn1(name,age){ alert(name+"2");}fn1("zs");
比如上面的脚本中调用fn1之后,最后调用的是第二个,这该如何理解
var fn1 = function(name){ alert(name+"1");};var fn1 = function(name,age){ alert(name+"2");};fn1("zs");
方法的定义可以理解成上面这个代码片段,刚开始fn1指向第一个,然后fn1指向第二个
然后调用fn1的时候就会 调用第二个。
原理部分:定义函数,其实就是等于定义一个对象,通过Function来定义,下面以例子来解释
var fn1 = new Function("name","alert(name+"+1+");");var fn1 = new Function("name","age","alert(name+"+2+");");fn1("zs");
Function 对象中可以接受的参数是不定的,但是有一个规则:最后一个参数一定是方法体
从上面可以看出来其实每个方法其实也是个Function对象,也就是说方法本身也是个对象,所以 返回一个方法是很正常的,就等于返回个对象这样
方法的特性
既然说函数是对象,对象一般都有属性和方法,比如每个方法都有一个length属性,这个属性指的是 这个函数期望接受的参数个数,说到这里要提到一个特殊的用法arguments。arguments指的是函数实际接受的参数封装成的数组。
function fn1(){ }alert(fn1());
上面的语法片段会打印 undefined,也就是说没有返回值的情况,就会返回undefined
在这里提一下,其实undefined是从null派生出来的,也就是说如果一个var a==undefined是true,那么a肯定==null也是true。
nul和undefined的深层次区别 参考:http://developer.51cto.com/art/201401/426966.htm
对象的创建
参考W3C中JavaScript
- 最原始方法
var oCar = new Object;oCar.color = "blue";//也可以oCar["color"] = "blue";oCar.showColor = function() { alert(this.color);};
这个是最原始的,他有一点特别不好,如果想创建一百个对象,就要写一百遍这样的代码,所以产生了工厂方式
- 工厂方式
function createCar(sColor,iDoors,iMpg) { var oTempCar = new Object; oTempCar.color = sColor; oTempCar.showColor = function() { alert(this.color); }; return oTempCar;}var oCar1 = createCar("red",4,23);var oCar2 = createCar("blue",3,25);oCar1.showColor(); //输出 "red"oCar2.showColor(); //输出 "blue"
这里最好的是把函数搞成共享的,把函数写到外面,然后把showColor指向那个函数即可。从功能上讲,这样解决了重复创建函数对象的问题;但是从语义上讲,该函数不太像是对象的方法。所有这些问题都引发了开发者定义的构造函数的出现。
- 构造函数方式
functon show(){ alert(this.color);}function Car(sColor,iDoors,iMpg) { this.color = sColor; this.showColor = show; //this指向调用者}var oCar1 = new Car("red",4,23);var oCar2 = new Car("blue",3,25);
在执行第一行代码前先创建一个对象,只有用 this 才能访问该对象。然后可以直接赋予 this 属性,默认返回值也是this,这种方式比起工厂方式就更像后台语言定义类了
- 原型方式
function Car() {}Car.prototype.color = "blue";Car.prototype.showColor = function() { alert(this.color);};var oCar1 = new Car();var oCar2 = new Car();
在这段代码中,首先定义构造函数(Car),其中无任何代码。接下来的几行代码,通过给 Car 的 prototype 属性添加属性去定义 Car 对象的属性。调用 new Car() 时,原型的所有属性都被立即赋予要创建的对象,意味着所有 Car 实例存放的都是指向 showColor() 函数的指针。从语义上讲,所有属性看起来都属于一个对象,因此解决了前面两种方式存在的问题。
alert(oCar1 instanceof Car); //输出 "true"
非常重要的一点是,通过原型定义的字段和方法都是所有事例共享的,就类似于JAVA的静态方法
- 混合的构造函数/原型方式
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.drivers = new Array("Mike","John");}Car.prototype.showColor = function() { alert(this.color);};var oCar1 = new Car("red",4,23);var oCar2 = new Car("blue",3,25);oCar1.drivers.push("Bill");alert(oCar1.drivers); //输出 "Mike,John,Bill"alert(oCar2.drivers); //输出 "Mike,John"
这个就是利用上面两个综合产生的最经典方式。当然后面还有根据这个进行的扩展动态原型,但是个人认为哪个没有这种混合的看的更清晰。所以我最推荐这种
修改对象
这个我感觉W3C里面讲的太经典了。http://www.w3school.com.cn/js/pro_js_object_modifying.asp
对象的继承
对象继承分为两种,其中一个是对象冒充 一个是原型
- 对象冒充
function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.color); };}function ClassB(sColor) { this.newMethod = ClassA; this.newMethod(sColor); delete this.newMethod;}
所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:
其实这个只要懂this就非常好理解。 var b =new ClassB(“red”).当进入this.newMethod = ClassA后就是给b(也就是this)添加了一个新的变量,这个变量指向ClassA方法。 this.newMethod(sColor); 这句话就是调用这个方法(这也说明刚注册的方法就可以调用),调用这个方法后,在ClassA中里面的this就是classB的this,也就是b,这样到最后b就拥有了color属性和sayColor方法
但是对象冒充有一个缺点就是,ClassA中的原型 属性和方法,ClassB却继承不了
方法的call
all() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。例如:
function sayColor(sPrefix,sSuffix) { alert(sPrefix + this.color + sSuffix);};var obj = new Object();obj.color = "blue";sayColor.call(obj, "The color is ", "a very nice color indeed.");
上面这种obj就等于sayColor中的this,后面就是参数对应
function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.color); };}function ClassB(sColor) { ClassA.call(this, sColor);}var b =new ClassB();
过程
1、var b=new ClassB();
然后进入ClassB,首先隐式创建一个对象,这个对象就是this,也是返回的对象
2、ClassA.call(this, sColor);
this就是b,然后进入ClassA方法,classA方法中的this就是传入的this,也即是b,这样就完成了 继承。
apply()方法和call类似,只是传参数的时候不一样。
ClassA.call(this, sColor)==ClassA(this,new Array(sColor));
ClassA.call(this, sColor,name)==ClassA(this,new Array(sColor,name));
- 原型方式实现继承
function ClassA() {}ClassA.prototype.color = "blue";ClassA.prototype.sayColor = function () { alert(this.color);};function ClassB() {}ClassB.prototype = new ClassA();
记住标准写法是传ClassA的空的构造函数
这种方式真是太巧妙了,让ClassB.prototype等于ClassA的一个实例
这样凡是ClassB的实例都享有ClassA的静态方法和变量
因为标准是new ClassA的空的构造函数 所有这种方式只能继承ClassA的静态的变量和字段(也就是原型字段)
- 混合方式
function ClassA(sColor) { this.color = sColor;}ClassA.prototype.sayColor = function () { alert(this.color);};function ClassB(sColor, sName) { ClassA.call(this, sColor); this.name = sName;}ClassB.prototype = new ClassA();ClassB.prototype.sayName = function () { alert(this.name);};
这样经典的继承也就产生了。
- javaScript--创建对象
- Javascript创建对象
- JavaScript中创建对象
- Javascript创建对象
- javascript 创建对象
- javascript创建createXmlHttpRequest对象
- javascript 创建自定义对象
- javascript 创建一次性对象
- JavaScript对象的创建
- JavaScript对象的创建
- javascript对象创建过程
- javascript对象的创建
- 创建 JavaScript 对象
- javascript对象创建过程
- javascript 创建对象
- JavaScript 对象创建方法
- JavaScript 创建对象
- javascript创建对象
- 网页表单序列化
- acm_1004
- ThinkPHP 内置方法介绍
- 葵花宝典
- getsockname函数与getpeername函数的使用
- Javascript对象创建
- BZOJ3996 线性代数(最小割)
- 反编译的常用工具与使用方法
- C++中的static关键字
- linux学习笔记-0
- 从官网下载mod_jk.so
- C++面向对象高级编程(下)-Geekband
- 23.ELK实时日志分析平台之Beats平台搭建
- Linux笔记(62)——nginx安装与php集成