面向对象高级
table of contents
原型与继承
什么是原型?
一个函数可以看成一个类,原型(prototype)是所有类都有的一个属性
为什么要使用原型?
构造器创建对象的时候,实际上会有成员重复,如果使用构造器this.方法名=function(){}方式创建对象,那么每一个对象对应的方法就会重复
1.1以前的普通写法
//普通写法 :思考这里会存在什么问题 function Person( name ){ this.name =name; this.sayHello = function(){ console.log( 'my name is'+this.name ); } } var p1 = new Person( '张三' ); var p2 = new Person( '李四' ) p1.sayHello(); p2.sayHello(); console.log( p1.sayHello == p2.sayHello );//false
- 1.2在函数外部定义一个方法,指向内部this.方法
js
//普通写法 :思考这里如果会有n个method方法会存在什么问题
function Person( name ){
this.name =name;
this.sayHello = method;
}
var p1 = new Person( '张三' );
var p2 = new Person( '李四' )
p1.sayHello();
p2.sayHello();
console.log( p1.sayHello == p2.sayHello );//true
function method(){
console.log( 'my name is'+this.name );
}
- 1.3原型方法
- 重点:每一个该函数(Person)构造器(new Person())创建出来的对象,都会默认链接到该对象,如果访问对象的方法,而对象中没有定义,就会在这个构造函数.prototype表示的对象中去查找
js
//原型扩展方法,所有实例对象共享
function Person( name ){
this.name =name;
}
Person.prototype.sayHello = function(){
console.log( 'my name is'+this.name );
}
var p1 = new Person( '张三' );
var p2 = new Person( '李四' )
p1.sayHello();
p2.sayHello();
console.log( p1.sayHello == p2.sayHello );//true
- 重点:每一个该函数(Person)构造器(new Person())创建出来的对象,都会默认链接到该对象,如果访问对象的方法,而对象中没有定义,就会在这个构造函数.prototype表示的对象中去查找
从以上3种创造对象的方法进行比较,总结出自己的结论
结论
- 原型的好处
put down your conclusion here…..
原型的概念
针对构造函数而言,原型就是 构造函数的prototype 属性,常常称其为 原型属性
针对实例对象而言,原型就是 实例对象的 原型对象
构造函数原型三角形图
如何使用原型对象?
- 简单来说共享的方法放到原型中,而独有的数据与行为放到当前对象中
- 使用原型对象的2中方式
- 自己总结
proto和prototype
- 早起浏览器不支持 proto,火狐率先使用该属性,但是是非标准,基本现在新的浏览器都支持
- 使用构造函数, 就使用 prototype 属性访问原型
- 使用实例对象, 就使用 非标准的 proto 属性访问原型
继承
什么是继承
- 简单的来说就是别人没有的,自己拿过来用,就像自己的一样
原型与实例对象
- 在js中,方法定义在原型对象中,属性定义在实例对象中,实例对象调用方法的时候,实例对象本身没有的该成员的,但依旧可以调用该方法,好像这个方法就是该实例一样,因此我们称该实例对象继承自 原型对象
属性访问原则
- 1.对象在调用方法或访问属性的时候,首先在当前对象中查找,如果有该成员使用并停止查找,
- 2.如果没有该成员就向其原型对象中查找,如果找到使用并停止查找
- 3.如果没有没有找到,则向该对象的 原型对象 中的 原型对象中查找
- 4.最后会查找到Object.prototype上,如果还没有即返回null
function fn(name){ this.name = name; } fn.prototype.sayHello = function(){ console.log("My name is"+ this.name); } var f = new fn("张三"); f.sayHello = function(){ console.log("我的名字是"+this.name); } f.sayHello();//我的名字是张三
- 混合式继承
原型链
复杂的原型链图
练习:根据下面代码绘制对象的原型链结构
function Person( name, age, gender ) { this.name = name; this.age = age; this.gender = gender; } function Student () {} Student.prototype = new Person( '张三', 19, '男' ); var stu = new Student();
递归面试题
面试题1->使用递归->封装实现 getElementsByClassName()方法
面试题2
var length = 10; function fn(){ console.log(this.length); } var obj={ length:5, method:function(fn){ fn(); arguments[0](); } } obj.method(fn,1);