OOP-ECMAScript - 深入理解Javascript
一、面向对象概论
x = {a: 10}; y = {b: 20}; y.Prototype = x z = {c: 30}; z.Prototype = y; z.a; // 10 x.a = 100; z.a; //100 /* 基于原型的基本概念 1. 基本概念是对象 2. 对象动态可变,完全可以从一个类型转换成另一个类型 3. 对象不需要类 4. 对象可以有原型,当对象没法响应对应属性,则可以委托给原型 */ // 一、 多态 //一个函数应用于不同对象 function test() { } test.call({ a: 10, b: 20 }); test.call({ a: 100, b: 200 }); var a = 1; var b = 2; test(); //1,2 //Date.prototype.getTime()例外,必须对应日期对象 new Date()===> Date.prototype.getTime.call(new Date()); // 二、封装 (function () { //初始化上下文 }()); // 三、不支持多重继承:一个对象可以用来做直接原型 // 四、AOP特性 // 装饰者例子:新增一个判断条件,AOP切入报错 function Decorator(oldFunction) { //匿名封装原有函数的执行,新增装饰的过程 return function () { //新增装饰的业务 if (fooBar !='test') { alert("wrong"); return false; } //执行原有函数 return oldFunction(); } } function test() { alert("right"); } var checkTest = new Decorator(test); var fooBar = false; checkTest();
二、ECMAScript中的OOP
/* ECMAScript:基于原型的委托式继承的面向对象语言 */ /* 一、数据类型 1. 原始值 Undefined, Null, Boolean, String, Number, Object Reference: 解释delete、typeof、this List: 描述参数列表行为 Completion 解释break、continue、return、throw */ var a = undefined; var b = null; var c = true; var d = 'test'; var e = 10; // 2. Object类型 var x = { a: 10,//原始值 b: { z: 100 },//对象 c: function () { }//函数 } // 3. 动态性:程序执行时可随意增删改对象属性 var foo = { x: 20 }; foo.y = 30;//新增 foo.x = function () { }//修改 delete foo.x; //静态对象不能修改 Object.freeze(foo);//此时属性不能进行任何操作 //设置属性只读、不可配置 Object.defineProperty(foo, "y", { value: 20, writable: false, //不可写 configurable: false //不可配置 }); // 4. Boolean、String、Number对象:由内置构造函数创建 var c = new Boolean(true); var d = new String('test'); var e = new Number(10); // 转换成原始值 // 使用不带new关键字的函数 c = Boolean(c); d = String(d); e = Number(e); // 重新转换成对象 c = Object(c); d = Object(d); e = Object(e); //其他内置构造函数创建:Function、Array、RexExp、Math、Date /* 二、构造函数 */ function A(x) { }//构造函数 var a = new A(); /* 三、原型 */ function A() { this.x = 10; } var a = new A(); A.prototype.y = 20; a.y;//undefined var b = new A(); b.y = 20; /* 四、读写特性 */ //Get方法 (function () { if (O.hasOwnProperty(P)) { return O.P; } }()); //Set方法 (function () { var foo = {}; foo.y = 30;//设置 }()); //属性访问器,针对对象 var foo = { a: 10 }; foo.a; foo["a"] //原始值报错:对原始值进行属性取值,先对对象包装,访问属性,然后删除属性 var a = 10; a.toString(); //"10" a.x = 4; a.x //undefined var a = new Number(10); a.toString(); a.x = 4; delete a;//所以无法访问
三、OOP小测
//一 if (!("a" in window)) { var a = 1; } alert(a); //答案:undefined //因为JavaScript引擎首先会扫描所有的变量声明,然后将这些变量声明移动到顶部 var a; if (!("a" in window)) { a = 1; } alert(a); //2 var a = 1, b = function a(x) { x && b(--x); }; alert(a);//永远是1 //填充VO的顺序是: 函数的形参 -> 函数申明 -> 变量申明 ->函数表达式 function a(x) { return x * 2; } var a; alert(a); //function //3 function b(x, y, a) { arguments[2] = 10; //活动对象,是当进入上下文时才创建,所以 a为Undefined alert(a); } b(1, 2); //4 function a() { alert(this); } a.call(null);//[object window] //如果第一个参数传入的对象调用者是null或者undefined的话,call方法将把全局对象(也就是window)作为this的值