2019独角兽企业重金招聘Python工程师标准>>>
JavaScript基于对象编程
1、JavaScript变量/函数声明在代码执行之前被解析,并且变量声明优先级高于函数声明。
代码片段:
1 2 3 4 5 6 7 | var flag = 'test' in window; if (!flag){ var test = 1; }
new StringBuffer( 'test = ' ).append(test).toString(); |
执行结果:
test = undefined
2、JavaScript中的this关键字指向当前执行上下文对象。
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var _this = this ; var id; var name; function User(){ id = 110; this .name = 'andy' ; return this ; }
var userOject = new User(); var _new_id = id; var _new_name = name; var _obj_id = userOject.id; var _obj_name = userOject.name;
var userFunc = User(); var _id = id; var _name = name; var _func_id = userFunc.id; var _func_name = userFunc.name;
new StringBuffer( '_this = ' ).append( _this ). append( ';userOject = ' ).append(userOject ).append( ';_new_id = ' ).append(_new_id).append( ';_new_name = ' ).append(_new_name ). append( ';_obj_id = ' ).append(_obj_id ).append( ';_obj_name = ' ).append( _obj_name ). append( ';userFunc = ' ).append(userFunc ).append( ';_id = ' ).append(_id ).append( ';_name = ' ).append(_name). append( ';_func_id = ' ).append(_func_id ).append( ';_func_name = ' ).append( _func_name).toString(); |
执行结果:
_this = [object Window]
userOject = [object Object]
_new_id = 110
_new_name = undefined
_obj_id = undefined
_obj_name = andy
userFunc = [object Window]
_id = 110
_name = andy
_func_id = 110
_func_name = andy
3、JavaScript中通过new关键字调用的函数才是构造函数。(在构造函数内部 - 也就是被调用的函数内 - this 指向新创建的对象 Object。)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 | function User(userName){ this .userName = userName; return this ; } var zhengwei = User( '郑伟' ); var andy = new User( 'andy' );
new StringBuffer( 'zhengwei.constructor = ' ).append(zhengwei.constructor). append( ';zhengwei instanceof User =' ).append((zhengwei instanceof User)). append( ';andy.constructor = ' ).append(andy.constructor). append( ';andy instanceof User = ' ).append((andy instanceof User)).toString(); |
执行结果:
zhengwei.constructor = [object Window]
zhengwei instanceof User =false
andy.constructor = function User(userName){this.userName = userNamereturn this}
andy instanceof User = true
4、JavaScript中所有变量都是对象,除了两个例外 null 和 undefined。
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | var undefind_test = 'undefind' in window; var null_test = 'null' in window; var _undefind = null ;
var undefind_toString; try { undefind_toString = undefind.toString(); } catch (e){ undefind_toString = e; }
var null_toString; try { null_toString = null .toString(); } catch (e){ null_toString = e; }
var boolean_toString = false .toString(); var number_toString = (2..toString() || 2 .toString() || (2).toString()); var array_toString = [1,2,3].toString();
new StringBuffer( 'undefind_test = ' ).append(undefind_test). append( ';null_test = ' ).append( null_test). append( ';_undefind = ' ).append(_undefind). append( ';undefind_toString = ' ).append(undefind_toString). append( ';null_toString = ' ).append(null_toString). append( ';boolean_toString = ' ).append(boolean_toString). append( ';number_toString = ' ).append(number_toString). append( ';array_toString = ' ).append(array_toString).toString(); |
执行结果:
undefind_test = false
null_test = false
_undefind = null
undefind_toString = ReferenceError: undefind is not defined
null_toString = TypeError: null has no properties
boolean_toString = false
number_toString = 2
array_toString = 1,2,3
5、JavaScript的对象可以作为哈希表使用,主要用来保存命名的键与值的对应关系。使用对象的字面语法 - {} - 可以创建一个简单对象。这个新创建的对象从 Object.prototype 继承。
代码片段:
1 2 3 4 5 6 7 8 9 10 | var Person = {id : '001' , userName : '郑伟' }; Person.age = 28;
new StringBuffer( "Person = " ).append(Person). append( ";Person.constructor = " ).append(Person.constructor). append( ";(Person instanceof Object) = " ).append((Person instanceof Object)). append( ";Person['id'] = " ).append(Person[ 'id' ]). append( ";Person.userName = " ).append(Person.userName). append( ";Person['age'] = " ).append(Person[ 'age' ]).toString(); |
执行结果:
Person = [object Object]
Person.constructor = function Object() {[native code]
}
(Person instanceof Object) = true
Person['id'] = 001
Person.userName = 郑伟
Person['age'] = 28
6、JavaScript原型属性。(基于原型模型实现继承的对象最终形成原型链,新创建的对象的 prototype 被指向到构造函数的 prototype)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | var Person = function (){}; Person.prototype = new Object(); // early binding -- Class template Person.prototype.id = '001' ; Person.prototype.userName = '郑伟' ; Person.prototype.age = 28; Person.prototype.say = function (){ return "[id = " + this .id + ", userName = " + this .userName + ",age = " + this .age + "]" ; }
var person = new Person(); // later binding -- Instance template /*person.id = '001' person.userName = '郑伟'; person.age = 28; person.say = function(){ return "[id = " + this.id + ", userName = " + this.userName + ",age = " + this.age + "]"; }*/ var _prototype_toString = new StringBuffer(); var count = -1; for ( var n in Person.prototype) { if (count >= 0){ _prototype_toString.append( "," ); } _prototype_toString.append(n).append( "=" ).append(Person.prototype[n]); count ++; }
new StringBuffer( 'Object.prototype = ' ).append(Object.prototype). append( ';Object.constructor = ' ).append(Object.constructor). append( ';Object.prototype.constructor = ' ).append(Object.prototype.constructor). append( ';(person instanceof Object) = ' ).append((Person instanceof Object)). append( ';person.constructor = ' ).append(Person.constructor). append( ";person.say() = " ).append(person.say()). append( ";_prototype_toString = " ).append(_prototype_toString.toString()).toString(); |
执行结果:
Object.prototype = [object Object]
Object.constructor = function Function() {[native code]
}
Object.prototype.constructor = function Object() {[native code]
}
(person instanceof Object) = true
person.constructor = function Function() {[native code]
}
person.say() = [id = 001, userName = 郑伟,age = 28]
_prototype_toString = id=001,userName=郑伟,age=28,say=function (){return "[id = " + this.id + ", userName = " + this.userName + ",age = " + this.age + "]"}
7、基于构造函数(对象冒充)实现JavaScript对象继承。(支持多重继承,不支持instanceof关键字,多层继承时调用层次过多)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // Define baseClass. function BaseClass(id, name){ this .id = id; this .name = name; this .toString = function (){ return 'id = ' + this .id + ', name =' + this .name; }; }
// Define subclass. function SubClass(){ BaseClass.apply( this , arguments); this .identifer = arguments[arguments.length - 1]; this .toString = function (){ return BaseClass.prototype.toString.call( this ) + ', identifer = ' + this .identifer; }; }
var subClass = new SubClass(1, 'subClass' , '0001' );
new StringBuffer( 'subClass.toString() = ' ).append(subClass.toString()). append( ';subClass.constructor = ' ).append(subClass.constructor). append( ';(subClass.constructor === SubClass) = ' ).append((subClass.constructor === SubClass)). append( ';(subClass instanceof SubClass) = ' ).append((subClass instanceof SubClass)). append( ';(subClass instanceof BaseClass) = ' ).append((subClass instanceof BaseClass)).toString(); |
执行结果:
subClass.toString() = [object Object], identifer = 0001
subClass.constructor = function SubClass(){BaseClass.apply(this, arguments)this.identifer = arguments[arguments.length - 1]this.toString = function(){return BaseClass.prototype.toString.call(this) + ', identifer = ' + this.identifer}}
(subClass.constructor === SubClass) = true
(subClass instanceof SubClass) = true
(subClass instanceof BaseClass) = false
8、基于原型(代码模板)实现JavaScript对象继承。(不支持多重继承,支持instanceof关键字,多层继承时模版复用)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // Define baseClass function BaseClass(){} BaseClass.prototype.id = null ; BaseClass.prototype.name = null ; BaseClass.prototype.toString = function (){ return 'id = ' + this .id + ', name =' + this .name; };
// Define subClass function SubClass(){} SubClass.prototype = new BaseClass();
SubClass.prototype.identifer = null ; SubClass.prototype.toString = function (){ return BaseClass.prototype.toString.call( this ) + ', identifer = ' + this .identifer; };
// The subclass is instanced. var subClass = new SubClass(); subClass.id = 1; subClass.name = 'subClass' ; subClass.identifer = '0001' ;
// Output new StringBuffer( 'subClass.toString() = ' ).append(subClass.toString()). append( ';subClass.constructor = ' ).append(subClass.constructor). append( ';(subClass.constructor === SubClass) =' ).append((subClass.constructor === SubClass)). append( ';(subClass instanceof SubClass) = ' ).append((subClass instanceof SubClass)). append( ';(subClass instanceof BaseClass) = ' ).append((subClass instanceof BaseClass)).toString(); |
执行结果:
subClass.toString() = id = 1, name =subClass, identifer = 0001
subClass.constructor = function BaseClass(){}
(subClass.constructor === SubClass) =false
(subClass instanceof SubClass) = true
(subClass instanceof BaseClass) = true
9、基于 构造函数(封装类属性-成员变量) + 原型 (封装类行为-方法)实现JavaScript对象继承。(不支持多重继承,支持instanceof关键字,多层继承时模版复用)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // Define baseclass. function BaseClass(id, name){ this .id = id; this .name = name; } // Overwrite toString method. BaseClass.prototype.toString = function (){ return 'id = ' + this .id + ', name =' + this .name; };
// Define subclass. function SubClass(){ BaseClass.apply( this , arguments); this .identifer = arguments[arguments.length - 1]; } // Subclass extends base class. SubClass.prototype = new BaseClass(); SubClass.prototype.constructor = SubClass; SubClass.prototype.toString = function (){ return BaseClass.prototype.toString.call( this ) + ', identifer = ' + this .identifer; };
// The subclass is intanced. var subClass = new SubClass(1, 'subClass' , '0001' );
// Output new StringBuffer( 'subClass.toString() = ' ).append(subClass.toString()). append( ';subClass.constructor = ' ).append(subClass.constructor). append( ';(subClass.constructor === SubClass) =' ).append((subClass.constructor === SubClass)). append( ';(subClass instanceof SubClass) = ' ).append((subClass instanceof SubClass)). append( ';(subClass instanceof BaseClass) = ' ).append((subClass instanceof BaseClass)).toString(); |
执行结果:
subClass.toString() = id = 1, name =subClass, identifer = 0001
subClass.constructor = function SubClass(){BaseClass.apply(this, arguments)this.identifer = arguments[arguments.length - 1]}
(subClass.constructor === SubClass) =true
(subClass instanceof SubClass) = true
(subClass instanceof BaseClass) = true
10、基于 对象结构(哈希表key-value)实现JavaScript对象继承。(支持多重继承,不支持instanceof关键字,多层继承时模版迭代)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | // Define class factory. var ClassFactory = { createClass : function (){ // To defind the current constructor. var CurrentClass = function (){}; // Agreed the final parameter for the current class extends the prototype, for the rest of the parameters so as to realize the parent class. var extendsPrototype = arguments[arguments.length - 1] || {}; for ( var i in arguments){ if (i == arguments.length - 1) break ; var superClass = arguments[i]; var ordinal = superClass.ORDINAL = i; if ( 'function' === typeof (superClass)){ superClass = superClass.prototype; } var superPrototype = extendsPrototype[ordinal] = {}; for ( var key in superClass) { // Determine whether the current members of the current class if (superClass.hasOwnProperty(key)){ superPrototype[key] = superClass[key]; } else { extendsPrototype[key] = superClass[key]; } } }
// Prototype will expand after the prototype chain of pointing to the current class. CurrentClass.prototype = extendsPrototype; CurrentClass.prototype.constructor = CurrentClass; return CurrentClass; } }; // Define class A var A = ClassFactory.createClass({ width : 100, getWidth : function (){ return this .width; } });
// Define class B var B = ClassFactory.createClass({ width : 200, height : 100, getWidth : function (){ return this .width; }, getHeight : function (){ return this .height; } });
// Define class C var C = ClassFactory.createClass(A, B,{ width : 300, getWidth : function (){ return this .width; } });
// Initialize C object var c = new C();
// Output new StringBuffer( 'c.constructor = ' ).append(c.constructor). append( ';(c.constructor === C) = ' ).append((c.constructor === C)). append( ';(c instanceof C) = ' ).append((c instanceof C)). append( ';((c instanceof A) || (c instanceof B)) = ' ).append(((c instanceof A) || (c instanceof B))). append( ';c.getWidth() = ' ).append(c.getWidth()). append( ';c[A.ORDINAL].getWidth() = ' ).append( (c[A.ORDINAL]).getWidth() ). append( ';c[B.ORDINAL].getWidth() = ' ).append( (c[B.ORDINAL]).getWidth() ). append( ';c[B.ORDINAL].getHeight() = ' ).append( (c[B.ORDINAL]).getHeight() ).toString(); |
执行结果:
c.constructor = function (){}
(c.constructor === C) = true
(c instanceof C) = true
((c instanceof A) || (c instanceof B)) = false
c.getWidth() = 300
c[A.ORDINAL].getWidth() = 100
c[B.ORDINAL].getWidth() = 200
c[B.ORDINAL].getHeight() = 100
11、基于 构造函数(封装类属性-成员变量) + 原型 (封装类行为-方法)实现JavaScript对象继承推荐写法。(不支持多重继承,支持instanceof关键字,多层继承时模版复用)
代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | // Define class factory. var ClassFactory = { createClass : function (){ // To defind the current constructor. // TODO set member Variables var CurrentClass = function (){ if ( this .initialize){ this .initialize.apply( this , arguments); } }; // The current class to extends base class. var SuperClass = arguments[0] || '' ; if ( typeof (SuperClass) === 'function' ){ CurrentClass.prototype = new SuperClass(); } else { // If current class is base class, then current class prototype direct at Object prototype. CurrentClass.prototype = new Object(); } CurrentClass.prototype.constructor = CurrentClass;
// The current class to extend prototype. var extendsPrototype = arguments[arguments.length - 1] || {}; for ( var key in extendsPrototype){ CurrentClass.prototype[key] = extendsPrototype[key]; }
return CurrentClass; } } // Define base class. var SuperComponent = ClassFactory.createClass({ initialize : function (title, index){ this .rootNodeName = 'js_oo' ; this .className = 'demo_container' ; this .title = title; this .index = index; }, getScript : function (){ throw new Error( 'The method must be implemented sub class!' ); } }); // Define sub class. var TestComponent = ClassFactory.createClass(SuperComponent, { getScript : function (){ var _script = new StringBuffer(); _script.append( this .title); return _script.toString(); } });
var testComponent = new TestComponent( "TestComponent" , 2);
// Output new StringBuffer( 'testComponent.constructor = ' ).append(testComponent.constructor). append( ';(testComponent.constructor === TestComponent) = ' ).append((testComponent.constructor === TestComponent)). append( ';(testComponent instanceof TestComponent) = ' ).append((testComponent instanceof TestComponent)). append( ';(testComponent instanceof SuperComponent) = ' ).append((testComponent instanceof SuperComponent)). append( ';testComponent.getScript() = ' ).append(testComponent.getScript()).toString(); |
执行结果:
testComponent.constructor = function (){if(this.initialize){this.initialize.apply(this, arguments)}}
(testComponent.constructor === TestComponent) = true
(testComponent instanceof TestComponent) = true
(testComponent instanceof SuperComponent) = true
testComponent.getScript() = TestComponent