javascript基础学习六--原型与继承
回顾: 1、删除子元素 //从node中删除一个div node.removeChild(div); //如果div变量不存在 var div = document.getElementById('...'); node.removeChild(div); //假设node节点中只有一个div node.innerHTML = ''; 2、删除属性 var attrNode = node.getAttributeNode('属性名'); node.removeAttributeNode(attrNode); //removeAttribute是什么意思呢? node.removeAttributeNode('属性名'); //getAttributeNode //getAttribute 3、获取属性值 var attrNode = node.getAttributeNode('属性名'); attrNode.nodeValue; //简化 node.getAttribute('属性名');
思考:
Json:基于JavaScript语言的轻量级的数据交换格式(JavaScript Object Notiation)
对象字面量和json对象的区别
json对象有两种说法:一种是传统的json对象,一个是符合json协议的对象
符合json协议的对象要求所有的属性名必须带有双引号,表示字符串
Var o = {name : ‘jim’};
Var o = {“name” : “jim”};
1、为什么需要原型
a) 代码验证
b) 内存与性能的需求
2、函数的prototype属性
a) prototype指向一个对象
b) 构造函数创建的对象会默认“连接到”该对象上
c) 代码修改实现共享方法
3、原型的概念
a) 原型属性
b) 原型对象
__proto__
以前要访问原型,必须使用构造函数。无法直接使用实例对象访问原型
火狐最早引入属性__proto__表示使用实例对象引用原型,但是早期是非标准的
通过该属性可以允许使用实例对象直接访问原型
//function Person() {} //原型对象就是Person.prototype //那么只有使用构造函数使用才可以访问 //var o = new Person(); //以前不能直接使用o来访问原型对象 //现在有了__proto__后 //o.__proto__也可以直接访问原型对象 //那么o.__proto__ == Person.prototype //标志符:名字 //原型对象中默认有‘constructor’,构造器构造函数
继承的概念
拿来主义:自己没有的,别人有的,拿过来自己用
1、最简单的继承就是将别的对象的属性强加到我的身上,那么我就有这个成员了 2、利用原型可以实现继承,不需要在我的身上添加任何成员,只要原型有了,我就有了 3、结论:将属性,方法等成员利用混入(mix)的办法,加到构造函数的原型上,构造函数的原型就都有了
为什么需要继承?
方法复用(*)
方法共享
混合式继承复杂描述(前面的知识)
1、new DivTag()用来创建Div对象 2、appendTo 加到某元素上 3、扩展 4、无论方法怎么写,方法是谁调用的this就是谁
混合式继承
// var Person = function () { // }; // var extend = function (o1,o2) { // for (var k in o2) { // o1[k] = o2 [k]; // } // }; // extend( Person.prototype, { // run : function () { console.log('我能跑了')}, // eat : function () { console.log('我能吃了')}, // sayHello : function () { console.log('你好')} // }); // var p1 = new Person(); // var p2 = new Person(); // p1.run(); // p1.eat(); // p1.sayHello(); // // p2.run(); // p2.eat(); // p2.sayHello(); //改良 var Person = function () {}; Person.prototype.extend = function(o){ for (var k in o) { this[k] = o[k]; } }; Person.prototype.extend({ run : function () { console.log('我能跑了')}, eat : function () { console.log('我能吃了')}, sayHello : function () { console.log('你好')} }); var p1 = new Person(); var p2 = new Person(); p1.run(); p1.eat();
p1.sayHello(); p2.run(); p2.eat(); p2.sayHello();
面试题
1、逻辑中断
a) Foo = foo || bar;
b) ||逻辑或,左边如果为真,那么整个表达式的值就是左边的值
c) ||如左边的值为假,整个表达式的值就是右边的值
d) 如果考虑函数参数的时候,一般使用该方法来兼容处理参数
原型存在的目的就是实现继承
js是基于原型继承的面向对象语言
使用点语法给原型添加成员与使用直接替换修改原型对象的区别:
1、原型指向发生了变化 2、构造函数做常见的对象所继承的原型不同 3、新增的对象默认是没有constructor属性
注意:在使用替换的方式修改原型的时候一般会添加constructor属性,在构造函数内部需要多次调用构造函数必须使用构造函数
构造函数在调用的时候,根据不同的参数创建不同的对象
静态成员与实例成员的概念
也是从面向对象的编程语言中引入的
1、静态成员表示的是静态方法和静态属性的概念,所谓静态就是构造函数提供的 2、实例成员表示的是实例方法和实例属性。实例是由构造函数创建的对象 3、一般工具型方法都由静态成员提供,跟实例有关由实例成员表示
构造原型实例三角形
//绘图练习 //1 function Person() { this.name = '张三'; this.sayHello = function (){} } var p = new Person();
//2 function Person() { this.name = '张三'; } Person.prototype.sayHello = function (){}; var p = new Person();
//3 function Person() { this.name = '张三'; } Person.prototype = { sayHello : function(){} }; var p = new Person();
原型与继承小结:
1、什么是原型? 2、如何使用原型?为了继承 a) 利用点添加成员(Person.prototype.成员) b) 直接替换添加成员(Person.prototype = {}) 3、什么是原型继承? a) 实例对象继承自原型对象 b) 一般的开发方式:属性交给构造函数,方法交给原型 4、如何实现? a) 混合继承方式:利用混入的方法给原型添加成员(方法和属性),那么实例就可以继承指定的方法和属性 b) 直接替换原型对象
//例如要实现一个自定义集合(数组) //弄一个类型Per function Per() {} //要提供数组的方法为其添加成员 Per.prototype = [ ]; var arr = new Per(); arr.push( 123 ); arr.push( 456 ); arr.push(1,2,3,4,5,6,7); //由于数组的方法push是首先将元素加到数组结尾处,然后将其长度+1 var str = arr.join( '=' ); alert (str ); 1\ function Collection (){} //要提供数组的方法为其添加成员 Collection.prototype = [];//能够防止数据污染 // Collection.prototype = Array.prototype; var arr = new Collection(); arr.push('a','b','c'); //自定义的集合目的是让其像所有数组一样使用,但是同时有一些数组无法实现的方法 //例如:sum Collection.prototype.sum = function(){}; alert([].sum);
2\ function Collection (){} //要提供数组的方法为其添加成员 //Collection.prototype = [];//Array.prototype Collection.prototype = Array.prototype;//效率高 var arr = new Collection(); arr.push('a','b','c'); //自定义的集合目的是让其像所有数组一样使用,但是同时有一些数组无法实现的方法 //例如:sum Collection.prototype.sum = function(){}; alert([].sum);
从案例中引出的问题
1、什么时候会得到undefined
2、我们介绍的是在实例中没有就到原型中找,但是原型中没有?
属性搜索原则
1、原型链 2、属性搜索原则 a) 所谓的属性搜索原则就是对象在访问属性和方法的时候,首先在当前对象中查找 b) 如果当前对象没有,那么在其原型中没有 c) 原型没有就到原型的原型中找,循环往复,直到object.prototype没有就返回undefined d) 如果是搜索方法就报错