设计模式之原型,学习笔记

  在常见的编程语言中如果你需要一个对象,那么可以通过类来创建,但是Javascript它并没有类这个概念,javascript创建对象是通过克隆另外一个对象而来的,既然如此那么它肯定有一个基类,这个基类就是Object.prototype,这是一个顶级根对象,其他所有对象都是通过克隆它而来的,比如你通过new Object()实际上就是克隆了Object.prototype。通过克隆我们可以得到一个一模一样的对象,但是这个prototype原型只有函数才有,因此我们得先创建一个函数,如下:

function Fn(){
  this.name = ‘JS‘;
}
Fn.prototype.sayHello = function(){
  alert(this.name);
};

var js = new Fn();
console.log(js);

  这里我们用到了new ,实际上new干了两件事一个是把Fn里面的this指向了js另外一件事就是js的__proto__指向了Fn.prototype,__proto__属于隐藏的属性,但是谷歌浏览器和火狐浏览器控制台已经公开了。__proto__的作用就是,当你这个对象没有某些方法或者属性的时候,这个对象就会通过__proto__上面找,__proto__又指向了那个构造函数的prototype,因此它又跑去prototype上面找对应的属性或方法。

下面我们手动模拟一下new的实现

function createObj(fn){
  var obj = new Object();
  fn.call(obj); //通过call让fn里面的this指向obj
  obj.__proto__ = fn.prototype; //指向fn.prototype 继承方法和属性
  return obj;
}
console.log(createObj(Fn));

  new的内部实现可能要比这复杂,但大致是这样的一个过程。

  ES5提供了一种新的克隆对象方法它叫Object.create(对象);

var obj = {a:1,b:2};
var cloneObj = Object.create(obj);
console.log(cloneObj);

  如果你通过谷歌浏览器你可以看到这样一个画面。

Object {}
  __proto__: Object
    a: 1
    b: 2
    __proto__: Object

  也就是说这个Object.create这个方法实际上就是将cloneObj的__proto__指向了obj。Ok我们也来实现一个。

var obj = {a:1,b:2};

function createObj(obj){
  function Fn(){
  }
  Fn.prototype = obj;
  return new Fn();
}
console.log(createObj(obj));

  有可能你会奇怪,正如我之前郁闷一件事,就是为什么不直接return返回这个obj不就好了吗。

var obj = {a:1,b:2};

function createObj(obj){
  return obj;
}
console.log(createObj(obj));

  虽然你看上去没啥区别,但其实不是这样,实际上通过prototype并不是去真正的创建一个对象,而是继承,这很重要,如果你按照上面的那种错误做法是真的去创建了另一个对象了,这样的话内存中又多出来一个对象,而往往我们没有必要这样做,只是希望如果本身这个对象没有的话,我在去继承你那个对象,这样不岂妙哉。

  通过Object.create来创建对象多少和new Object()还是有区别的,首先Object.create支持传递一个null,如果传的是null的话,它创建的真的是一个彻彻底底的空对象,它的__proto__不指向任何东西,因此它不继承任何的属性和方法,而new Object()创建的它的__proto__指向Object.prototype,简单来说Object.create(null)没有原型,即一个空对象,而new Object()有原型对象。

时间: 2024-12-21 21:57:45

设计模式之原型,学习笔记的相关文章

设计模式--单例模式(学习笔记)

定义:      单例模式:保证一个类只有一个实例,并且提供一个访问它的全局访问点.(<大话设计模式定义>): 单例模式分为两种: 1>饿汉式单例类:自己被加载时就将自己实例化. 例子:       private SingleExample() {           } private static SingleExample singleExample=new SingleExample(); @Override protected SingleExample getInstanc

[GeekBand] 设计模式之观察者模式学习笔记

本文参考文献::GeekBand课堂内容,授课老师:李建忠 :网络资料: http://blog.csdn.net/hguisu/article/details/7556625 本文仅作为自己的学习笔记,不代表权威,因为是初学,有错误烦请大家指正,谢谢. 1.什么是观察者模式,应用场所有哪些? 观察者模式(有时又被称为发布-订阅Subscribe>模式.模型-视图View>模式.源-收听者Listener>模式或从属者模式)是软件设计模式的一种.在此种模式中,一个目标物件管理所有相依于它

[GeekBand] 设计模式——工厂模式学习笔记

 本文参考文献:GeekBand课堂内容,授课老师:李建忠 :大话设计模式 其余的模式方法请自行查看Geekband相关课程,在此不累述. 这周的课题是: 针对DrawingSystem中的基类Shape和各个子类Line.Rec.Circle.为支持更多的形状子类,请使用某种模式来支持灵活地创建它们.使用松耦合面向对象设计方法和思想,可使用伪码表示设计. 课程中提到了四种模式,“工厂方法”.“抽象工厂”.“原型模式”.“构建器”模式.最后聚焦在了“工厂方法”和“抽象工厂”这两种方法,那么第一个

设计模式之禅学习笔记

现在比较熟悉的设计模式有: slf4j=>单例模式,工厂模式,门面(外观)模式 工厂模式 vs 抽象工厂模式 工厂模式 接口,接口实现类,工厂类 抽象工厂模式 接口,借口实现类,工厂抽象类,具体的工厂实现类.红色句子是二者唯一的区别 工厂模式 vs 建造者模式 工厂模式是生产整个产品 建造者模式是重点强调建造的过程 模板模式 spring的很多类都应用了这种模式 比如一个抽象类,有很多具体的实现类继承这个抽象类 抽象类跟接口相比,优点是如果在抽象类中添加新的具体实现方法,不会影响之前已经继承的实

原型学习笔记

1.for...in... :列出对象中所有的属性,包括原型中的属性: 2.hasOwnProperty() :查询是否是对象自己的属性,不包括原型: 3.propertyIsEnumerable() :对所有的非内建对象属性返回true: //如果可以用for...in...枚举出来则返回true; 4.isPrototypeOf() :返回当前对象是否是另一个对象的原型. 获得原型: ES5中   Object.getPrototypeOf()    不支持getPrototypeOf的可以

Javascript原型学习笔记

三个基本概念:构造函数.原型.实例   每一个构造函数都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针(constructor),而实例都包含一个指向原型的内部指针(__proto__). emp1: function Foo(y){ this.y = y ; } Foo.prototype.x = 10; Foo.prototype.calculate = function(z){ return this.x+this.y+z; }; var b = new Foo

JS原型学习笔记

1.原型是函数对象的属性,它的初始值是一个空对象,这个prototype原型对象可以添加方法和属性. 2.构造器对象查找属性和方法时先查找构造器后查找原型. 3.若构造器中的属性和原型中的属性相同,构造器的优先级会高于原型. 4.枚举属性(for-in) (1).数组枚举 var a=[1,2,3]; for(var i in a){ console.log(a[i]); } (2).对象枚举 var a={name:"gao",age:"18",sex:"

js类、原型——学习笔记

js 内置有很多类,我们用的,都是从这些类实例化出来的. 1 function Object () {} 2 function Array () {} 3 function String () {} 4 function Boolean () {} 5 function Function () {} 比如,var a = {};等同于var a = new Object(); var a =[];等同于var a = new Array(); 现在我们要创建一个自定义的类.在SmartList.

《JS高程》对象&amp;原型学习笔记

ECMA-262 把对象定义为:”无序属性的集合,其属性可以包含基本值.对象或者函数.”可以把 ECMAScript 的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数. 6.1.理解对象 创建自定义对象的两种方式: (1)创建一个 Object 的实例: var person = new Object(); (2)对象字面量(首选): var person = {}; ---------------------------------------------------------

java/android 设计模式学习笔记(13)---享元模式

这篇我们来介绍一下享元模式(Flyweight Pattern),Flyweight 代表轻量级的意思,享元模式是对象池的一种实现.享元模式用来尽可能减少内存使用量,它适合用于可能存在大量重复对象的场景,缓存可共享的对象,来达到对象共享和避免创建过多对象的效果,这样一来就可以提升性能,避免内存移除和频繁 GC 等. 享元模式的一个经典使用案例是文本系统中图形显示所用的数据结构,一个文本系统能够显示的字符种类就是那么几十上百个,那么就定义这么些基础字符对象,存储每个字符的显示外形和其他的格式化数据