博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript OOP(上)(八)
阅读量:5942 次
发布时间:2019-06-19

本文共 2719 字,大约阅读时间需要 9 分钟。

一、OOP的概念和继承

1、OOP概念

 面向对象程序设计(Object-oriented programming,OOP)是一种程序设计范型,同时也是一种程序开发的方法。对象指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

OOP特点:继承、封装、多态和抽象。

2、基于原型的继承

 

function Foo(){    this.y=2;}/*每个函数对象有一个对象属性prototype,这个prototype是个对象,Fooj就是Foo.prototype*/Foo.prototype.x=1;var obj3=new Foo();/*创建一个Foo的实例obj3,使用new调用的时候,Foo作为构造器来使用,并且this指向一个对象,而这个对象的原型会指向构造器的prototype属性,也就是Foo.prototype*/console.log(obj3.y);  //2  对象上的console.log(obj3.x);   //1 原型上的

3、prototype属性与原型

用函数声明创建一个空函数function Foo(){}的时候,函数就会有一个prototype对象属性。

prototype对象属性默认会有2个属性,一个是constructor,会指向它本身Foo;另外一个是_proto_,一般的对象都会指向Object.prototype。

x:1是通过赋值语句Foo.prototype.x=1;增加的。

Foo.prototype的作用:

当使用new Foo去构造Foo的实例的时候,这个prototype属性会用作new出来的对象(obj1,obj2,obj3...)的原型(_proto_)。

prototype:是函数对象上面预设的对象属性。

_proto_:对象上的原型,通常都是它的构造器的prototype属性。

4、更复杂的实例:

Student继承Person

二、原型链

如下:

从后往前:

bosn构造:通过 new Student()创建了bosn实例,bosn实例的原型_proto_指向构造器的prototype属性,也就是Student.prototyep。Studnet.prototype上面有hi()方法和learn()方法。

Studnet.prototype构造:通过Object.create(Person.prototype)来构造。Student.prototype是个空对象,这个空对象随后添加了hi()方法和learn()方法,它的原型_proto_指向了Person.prototype。

Person.prototype:直接定义了一个Person函数,在Person.ptototype上添加了共享的属性和方法,这个Person.prototype就是一个内置的普通对象。它本身也会有原型就是Object.prototype。

坑1:

并不是所有的对象,最终原型链上都有Object.prototype。

通过Object.create(null)创建的对象原型链上没有Object.prototype,也就没有Object.prototype上的方法。

坑2:

并不是所有的函数对象都会有prototype属性。

ES5的bind()函数用来修改函数在运行时的this。

bind方法返回的也是一个函数,可以通过typeof判断一下,但是bind()方法返回的函数就没有prototype属性。

三、prototype属性

1、prototype相关的修改

/*给prototype添加属性和方法会影响到已创建或新创建的实例*/Student.prototype.x=101;console.log(bosn.x);     //101/*修改prototype并不会影响已经创建的实例,会影响后续创建的实例*/Student.prototype={y:2};console.log(bosn.y);       //undefinedconsole.log(bosn.x);      //101var nunnly=new Student('Nunnly',3,'Class LOL KengB');console.log(nunnly.x); //undefinedconsole.log(nunnly.y);  //2

2、内置的构造器的prototype

 内置的函数构造器也有prototype属性,比如Object,Number,Boolean,Function,等等。

bind,apply,call等等都是从Function的prototype上取到的。

边际效应:

修改这些构造器的prototype有时候会带来一些边际效应。

Object.prototype.x=1;var obj={};console.log(obj.x); //1for(var key in obj){    console.log('result: '+key);}//result: x

边际效应:在prototype上添加属性x,在for in遍历的时候会把x遍历出来。

解决办法:

ES5里面有defineProperty来控制对象属性。默认标签都是false,下面只设置writable:true。简洁表示不可枚举,也不可配置。

Object.defineProperty(Object.prototype,'x',    {writable:true,value:1});var obj={};console.log(obj.x); //1for(var key in obj){    console.log('result: '+key);}//nothing output here

这样for in的时候就不会有边际效应。所以如果写nodejs,判断一下如果有defineProperty,可以通过这种方式来改写Object.property这样一些内置构造器上的prototype的时候,可以跨过这样一个边际效应。

很少会用到修改Object.prototype,因为影响范围太广了。 但是有时候为了兼容性可能会通过Object.defineProperty做一些ES5才支持的方法模拟。

四、实现继承的方式

见代码。

 

本文作者,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:有问题欢迎与我讨论,共同进步。 

 

你可能感兴趣的文章
jQuery操作input
查看>>
layer弹出信息框API
查看>>
delete from inner join
查看>>
WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...
查看>>
git merge 和 git merge --no-ff
查看>>
独立软件开发商进军SaaS注意八个问题,互联网营销
查看>>
jdk内存的分配
查看>>
关于self.用法的一些总结
查看>>
UIView翻译 (参考)
查看>>
Android Display buffer_handle_t的定义
查看>>
SSH详解
查看>>
ASM概述
查看>>
【290】Python 函数
查看>>
godaddy域名转发(域名跳转)设置教程
查看>>
silverlight学习布局之:布局stackpanel
查看>>
理解并自定义HttpHandler
查看>>
小程序二次贝塞尔曲线,购物车商品曲线飞入效果
查看>>
微信小程序
查看>>
常用的正则表达式分享
查看>>
我的世界:一个村落(其一)
查看>>