JavaScript之原型模式

JavaScript中有这样的一个概念,对象。

有不少人觉得Java这么语言才是面向对象的语言,JavaScript哪里面向对象了。

其实说JavaScript面向对象还不如说JavaScript基于对象。

例如:我们在对DOM进行操作的时候用到的一下方法 

var app = document.getElementById("app")
   app.style="width:100px"
   app.innerHTML="123"

 

我们获取了一个id为app的节点的时候,其实它就是一个对象。

然后我们通过".属性"来获取属性值或者给它赋值等等。

我们在看看一个例子!

 

var num = 123;
console.log(num.toString()); // “123”

 

 在这里我们定义了一个变量名为num,并且给它赋值为 数据类型为:Number ,值为123。

 然后我们通过num.toString() 方法 得出了字符串“123”,不是一般只有对象后面才能接 点属性名吗? obj.***

其实在JavaScript里万物皆可为对象。在这里我就不在一一细说了。

现在我们来研究一下什么是原型模式。

在JavaScript高级程序设计这本书里说道:

创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法
如果按照字面意思来理解,那么 prototype 就是通过调用构造函数而创建的那个对象实例的原型对象。(我们来看看代码)
  function Person() {
  }

在JavaScript里第一个字母大写的函数称之为构造函数。我们来看看这个函数里有什么?

 

 

 你会发现,这里真的有一个书上说的prototype(原型)属性。

理解原型对象
  无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个 prototype属性,这个属性指向函数的原型对象。
  在默认情况下,所有原型对象都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向 prototype 属性所在函数的指针。
  创建了自定义的构造函数之后,其原型对象默认只会取得 constructor 属性;至于其他方法,则都是从 Object 继承而来的。
  当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。

我们通过构造函数Person来创建一个实例出来来看看这个实例对象上有没有什么东西。

  function Person() {
  }
  Person.prototype.name="张三";
  var p1=new Person();
 console.log(p1.__proto__ === Person.prototype);  //true

 

 

 

你会发现通过构造函数创建出来的实例对象p1的(__proto__)属性 全等于 构造函数的prototype属性。

Firefox、Safari 和 Chrome 在每个对象上都支持一个属性__proto__

我们再通过Person构造函数来创建一个实例对象,来比较这两个对象。

function Person(age,sex) {
    this.age=age;
    this.sex=sex;
  }
  Person.prototype.name = "张三"
  var p1 = new Person(18,"男")
  var p2 = new Person(19,"女")
  console.log(p2 == p1) //false
  console.log(p1.__proto__ === p2.__proto__)  //true
  console.log(p1.name)  //张三
  console.log(p2.name) //张三
  console.log(p1.age)   //18
  console.log(p2.age)   //19
  console.log(p1.sex) //男
  console.log(p2.sex) //女
  p1.name="李四"

 console.log(p1.name) //李四 这是来自实例对象的属性name

console.log(p2.name) //张三 这是来自原型对象的属性name

在这里我们发现,实例对象p1与实例对象p2 的__proto__属性相等,这两个实例对象不相等,开始它们的name属性值相等。

而且构造函数里没有设置name属性,那么我们也可以通过p1.name,p2.name访问到,然后我们更改了p1.name的值。发现p1实例对象会追加一个name属性(JavaScript对象的动态性),然后再去访问p1,p2的name属性发现值不一样了。

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先
从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,
则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这
个属性,则返回该属性的值。

原来通过同一个构造函数创建出来的实例对象,他们的原型对象都 指向 构造函数的原型属性。

看看它们的关系图

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)