JS面向对象详解
来源:互联网 发布:mac怎么截gif 编辑:程序博客网 时间:2024/05/21 21:44
类理论
封装:强调数据和操作数据的行为本质上是相互关联的。好的设计就是将数据以及和它相关的行为封装(或者打包)起来。实例化:我们可以使用类对数据结构进行分类。可以把任意数据结构看作范围更广的定义中的一种实例。如“汽车”为“交通工具”的一种实例。继承:子类通过继承父类来对类进行相应的扩展。多态:父类的通用行为可以被子类用更加特殊的行为重写。注意:类理论强调父类和子类使用相同的方法名来表示特定的行为,从而让子类重写父类。但在JS代码中这样会降低代码的可读性和健壮性。
JS中的类理论
由于类是一种设计模式,在JS中可以通过一些方法实现类的功能。JS中提供了一些近似类的语法,如 new 、class等关键字。但这实质中只是一种语法糖。
类构造函数:是一种初始化一个类实例初始化所需要的所有信息的一种方法,这个方法名通常与类名相同,被称为构造函数。
class Foo{ private int a; //构造函数 Foo(int a){ this.a = a } public void methods() System.out.println("some methods"); } public static void main(String[] args){ Foo foo = new Foo("24"); //实例化一个类 } }
类的继承: 定义一个类,然后定义一个继承前者的类。每一个继承而来的类都是一个独一无二的存在。
class Bar extends Foo{ public void main(String[] args){ Bar bar = new Bar(); bar.methods(); //调用继承于父类的方法。 } }
类的多态:任何方法都可以引用继承层次中高层的方法。在继承链的不同层次中一个方法名可以被多次定义,当调用方法时会自动选择合适的定义。
class Baz extends Bar{ public void methods(){ System.out.println("my methods defined by myself"); } public static void main(String[] args){ Baz baz = new Baz(); //my methods defined by myself }}
混入和多重继承:JS中没有提供多重继承的机制。在继承或者实例化时,JS的对象机制并不提供自动执行复制行为。简单来说,JS中只有对象,并不存在可以被实例化的“类”,一个对象并不会被复制到其他对象,它们只是被关联起来。JS中使用方法来模拟类的复制行为。
显示混入
function mixin(sourceObj, targetObj){ for(var key in sourceObj){ if(!key in targetObj){ targetObj[key] = sourceObj[key]; } }}
隐式混入
function SupType(name,age){ this.name = name; this.age = age; } function SubType(name,age,job){ SupType.call(this,name,age); this.job = job; } var o = new SubType("Fzw","23","coder"); console.log(o); // {name:"Fzw",age:23,job:"coder"}
原型
定义:JS对象中有一个特殊的[[prototype]]内置属性,实质上是对其他对象的引用。几乎所有的对象在创建时[[prototype]]都会被赋予一个非空的值。当在对象中查找某一个属性的值时,会首先在对象本身上查找,否则会在对象的[[prototype]]进一步查找。这个过程会持续到找到匹配的属性名或者整条[[prototype]]被查询完。如果是后者,则返回undefined。
[[prototype]]的尽头:所有普通的[[prototype]]链最终都会指向内置的Object.prototype。
原型继承
SubType.prototype = SupType.prototype
这个等式并不会创建一个关联到SupType的新对象,它只是让SubType.prototype去直接引用SupType.prototype,当对SubType.prototype进行任何修改增删操作时,都直接修改SupType.prototype本身。
SubType.prototype = new SupType()(存在副作用的做法!)
这种做法确实会创建一个关联到SupType.prototype的新对象。但是调用了SupType的构造函数,其存在的一些具体副作用的方法如:修改状态、注册到其他对象或给this添加属性等。会间接影响SubType 的实例。
SubType.prototype=Object.create(SupType.prototype) Object.setPrototypeOf(SubType.prototypr, SupType.prototype)
两者实现的结果几乎一致,创建了一个无副作用且关联到SubType.prototype的新对象。区别在于前者使用于ES6之前,且存在一些性能上的损失,抛弃的对象需要进行垃圾回收。后者在ES6后可用。
检查类的关系
假设有对象Foo,如何寻找Foo对象委托的对象(假设存在)。
function Foo(){} Foo.prototype.name = "Foo"; function Bar(){} Bar.prototype = Object.create(Foo.prototype); function Baz(){} Baz.prototype = Object.create(Bar.prototype); var foo = new Foo(); var bar = new Bar(); var baz = new Baz(); console.log(bar instanceof Foo) //true console.log(baz instanceof Bar) //true console.log(baz instanceof Foo) //true //instanceOf 只能判断在foo的原型链中是否存在指向Foo.prototype的对象
使用函数方法判断[[prototype]]的反射问题
Foo.prototype.isPrototypeOf(bar); // true Bar.prototype.isPrototypeOf(baz); // true Foo.prototype.isPrototypeOf(baz); // true //和instanceof的效果一样 //使用Object.getPrototypeOf , 因代码的执行环境有差异 Object.getPrototypeOf(foo) == Foo.prototype;//true Object.getPrototypeOf(bar) == Foo.prototype;//false Object.getPrototypeOf(baz) == Foo.prototype;//false //使用__proto__属性(绝大对数支持一种非标准的方法来访问内部[[prototype]]属性) foo.__proto__ === Foo.prototype; //true bar.__proto__ === Foo.prototype; //false baz.__proto__ === Foo.prototype; //false //__proto__大致实现 Object.defineProperty(Object.prototype,"__proto__",{ get:function(){ return Object.getPrototypeOf(this); }, set:function(o){ Object.setPrototypeOf(this, o); return this; } });
关于Object.create
//ES5新增函数,ES6polyfill如下,实现Object.create的部分功能if(!Object.create){ Object.create = function(o){ function F(){} F.prototype = o; return new F(); }}//实际上,Object.create还可以在对象添加属性,并配置访问属性var obj = { a:24}var newObj = Object.create(obj, { b:{ enumerable:false, writable:true, configurable:false, value:3 }, a:{ enumerable:true, writable:false, configurable:false, value:4 }});newObj.hasOwnProperty("a"); //truenewObj.hasOwnProperty("b"); //truenewObj.hasOwnProperty("c"); //falseconsole.log(newObj) //{a:3,b:4}
原型继承本质:委托
原型链机制的本质是指向对象中的一个内部链接引用另一个对象。如果在第一个对象中没有查找到相应的属性或方法引用,那么JS引擎就会继续在[[prototype]] 关联的对象上进行查找。同理,如果后者也没有找到需要的引用就会继续查询它的[[prototype]],以此类推,这一系列对象被称为原型链。
阅读全文
0 0
- js面向对象详解
- JS面向对象详解
- 详解js面向对象编程
- JS面向对象编程详解
- js prototype 详解 js实现面向对象
- js prototype原型面向对象编程详解
- js prototype原型面向对象编程详解GOOD
- js面向对象尝试
- js面向对象
- 面向对象的js
- js中的面向对象
- JS面向对象
- JS面向对象2
- 06 JS面向对象
- JS 面向对象
- JS面向对象例子
- 面向对象 js 打包
- js面向对象设计
- Oracle 触发器
- leetcode
- 使用sudo apt-get update总是报错软件包缓存文件损坏
- 编辑器vi的使用
- python应用
- JS面向对象详解
- IO,异常
- Windows延迟删除、重命名
- Maven tomcat插件debug项目时 ,出现source not found的解决办法
- HDOJ1001
- 基于Dubbo的分布式系统架构(二):搭建一个简单的分布式架构
- ssh--applicationContext.xml
- 图片通过javaCV转RTMP流
- Privilegelnterceptor