JavaScript构造函数和原型
1. 前言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function Restudy ( ) { var ldh = { name : '刘德华' , age : 18 } console .log (ldh); var zxy = new Object () zxy.name = '张学友' zxy.age = 19 console .log (zxy); function Star (name, age ) { this .name = name; this .age = age; } var lm = new Star ('黎明' , 20 ) console .log (lm); }
2. 概念
3. new执行过程
new 在执行时会做四件事情:
① 在内存中创建一个新的空对象。
② 让 this 指向这个新的对象。
③ 执行构造函数里面的代码,给这个新对象添加属性和方法。
④ 返回这个新对象(所以构造函数里面不需要 return )。
4. 静态成员和实例成员
4.1 概念
4.2 实例成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function Star (uname, age ) { this .uname = uname; this .age = age; this .sing = function ( ) { console .log ('i 1can sing' ); } } var lm = new Star ('黎明' , 20 );lm.sing (); console .log (lm.uname );console .log (Star .uname );
4.3 静态成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function Star (uname, age ) { this .uname = uname; this .age = age; this .sing = function ( ) { console .log ('i 1can sing' ); } } var lm = new Star ('黎明' , 20 );Star .sex = 'man' console .log (Star .sex );console .log (lm.sex );
5. 构造函数的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function Star (uname, age ) { this .uname = uname; this .age = age; this .sing = function ( ) { console .log ('我会唱歌' ); } } var ldh = new Star ('刘德华' , 18 );var zxy = new Star ('张学友' , 19 );console .log (ldh.sing === zxy.sing );ldh.sing (); zxy.sing ();
6. 构造函数原型 prototype
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Star (uname, age ) { this .uname = uname; this .age = age; } Star .prototype .sing = function ( ) { console .log ('我会唱歌' ); } var ldh = new Star ('刘德华' , 18 );var zxy = new Star ('张学友' , 19 );console .log (ldh.sing === zxy.sing );ldh.sing (); zxy.sing ();
7. 对象原型 proto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Star (uname, age ) { this .uname = uname; this .age = age; } Star .prototype .sing = function ( ) { console .log ('我会唱歌' ); } var ldh = new Star ('刘德华' , 18 );var zxy = new Star ('张学友' , 19 );zxy.sing (); console .log (ldh.sing === zxy.sing );console .log (ldh);console .log (ldh.__proto__ === Star .prototype );
8. constructor 构造函数
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 function Star (uname, age ) { this .uname = uname; this .age = age; } Star .prototype = { constructor : Star , sing : function ( ) { console .log ('我会唱歌' ); }, act : function ( ) { console .log ('我会演戏' ); } } var ldh = new Star ('刘德华' , 18 );var zxy = new Star ('张学友' , 19 );console .log (zxy);console .log (Star .prototype );console .log (ldh.__proto__ );console .log (Star .prototype .constructor );console .log (ldh.__proto__ .constructor );
9. 构造函数、实例、原型对象三者之间的关系
1 2 3 1.构造函数的prototype属性指向了构造函数原型对象 2.实例对象是由构造函数创建的,实例对象的__proto__属性指向了构造函数的原型对象 3.构造函数的原型对象的constructor属性指向了构造函数,实例对象的原型的constructor属性也指向了构造函数
10. 原型链
10.1 概念
原型链是 JavaScript 中实现继承的一种机制。每个 JavaScript 对象都有一个内部属性 [[Prototype]],它指向另一个对象,这个对象就是当前对象的原型。如果在当前对象上访问一个属性或方法时,如果当前对象本身没有这个属性或方法,那么 JavaScript 就会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的末端(即 Object.prototype),如果还没有找到,那么就返回 undefined。
例如,假设有一个对象 obj,当你访问 obj.prop 时,JavaScript 首先会查找 obj 是否有属性 prop,如果没有,那么 JavaScript 就会查找 obj 的原型,也就是 obj.[[Prototype]] 所指向的对象,看看该对象是否有属性 prop,如果还是没有找到,那么 JavaScript 就会继续查找 obj 的原型的原型,以此类推,直到找到该属性或者到达原型链的末端。
JavaScript 中的原型链是一个单向的链表结构,每个节点都是一个对象,节点之间通过 [[Prototype]] 属性连接起来。当一个对象被创建时,它会自动关联到它的原型对象上,这种关联关系是通过 JavaScript 的 new 操作符实现的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function Star (uanme, age ) { this .uanme = uanme; this .age = age; } Star .prototype .sing = function ( ) { console .log ('i can sing' ); } var ldh = new Star ('刘德华' , 20 )console .log (Star .prototype );console .log (Star .prototype .__proto__ === Object .prototype );console .log (Object .prototype .__proto__ );
10.2 图解
10.3 成员查找机制(规则)
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 function Star (uanme, age ) { this .uanme = uanme; this .age = age; } Star .prototype .sing = function ( ) { console .log ('i can sing' ); } var ldh = new Star ('刘德华' , 20 )console .log (ldh.sex );
11. 原型对象this指向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function Star (uanme, age ) { this .uanme = uanme; this .age = age; } var thatStar .prototype .sing = function ( ) { console .log ('i can sing' ); that = this ; } var ldh = new Star ('刘德华' , 20 )ldh.sing () console .log (that === ldh);
12. 扩展内置对象
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 Array .prototype .sum = function ( ) { var sum = 0 ; for (var i = 0 ; i < this .length ; i++) { sum += this [i]; } return sum; } Array .prototype .differ = function (a, b ) { return a - b; } var arr = [1 , 2 , 3 , 4 , 6 , 6 , 7 , 7 , 8 , 9 ]console .log (arr.sum ());var arr1 = new Array (11 , 22 , 33 )console .log (arr1.sum ());console .log (arr.differ (arr[0 ],arr[1 ]));console .log (Array .prototype );
13. 继承
13.1 说明
13.2 call()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function fn (a, b ) { console .log ('自行车创造性' ); console .log (this ); console .log (a + b); } var demo = { name : 'solar' } fn.call (demo, 1 , 3 );
13.3 借用构造函数继承父类型属性
13.4 借用原型对象继承父类型方法
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 function Father (uname, age ) { this .uname = uname; this .age = age; } Father .prototype .money = function ( ) { console .log (100000 ); }; function Son (uname, age, score ) { Father .call (this , uname, age); this .score = score; } Son .prototype = new Father ();Son .prototype .constructor = Son ;Son .prototype .exam = function ( ) { console .log ('i can exam' ); } var son = new Son ('qwe' , 20 , 100 );console .log (son);son.money () son.exam () console .log (Father .prototype );console .log (Son .prototype .constructor );