原型与原型链

全局对象

ECMAScript规定全局对象叫做global,但是浏览器把window作为全局对象(浏览器先存在的)。
window就是一个哈希表,里面含有很多属性。
window 对象表示一个包含DOM文档的窗口,其 document 属性指向窗口中载入的 DOM文档 。使用 document.defaultView 属性可以获取指定文档所在窗口。
在标签浏览器(比如Firefox)中,每个标签具有自己的 window 对象。也就是说,同一个窗口的标签之间不会共享一个 window 对象。
无代码时,创建一个新页面window就会被创建。
window的属性就是全局变量。
这些全局变量分为两种:

1、一种是 ECMAScript 规定的

例如:

  • parseInt
  • parseFloat
  • Number
  • String
  • Boolean
  • Object

2、一种是浏览器自己加的属性

例如:

  • alert
  • prompt
  • comfirm
  • console.log
  • console.dir
  • document
  • document.createElement
  • document.getElementById

简单类型和对象的区别

1、创建一个number

var n = 1
var n = new Number(1)

这两个都是创建一个Number类型的数据,但是区别在于,第二个创建的是声明一个对象,因为js创建初期要求和java相像,所以才有了这种数据创建方式,虽然用第一种创建的是一个简单数据类型,但是却可以拥有toString,valueOf等函数,这是因为临时转换成一个temp临时对象,而这个对象中包含了那些函数

2、创建一个string

var s = 'string'
var s = new String('string')

创建string也有两种方法,第二种方法和第一种的区别就是,第二种创建的也是一个对象,具体和number是一样的

3、创建一个boolean

var b = true
var b = new Boolean(ture)

创建布尔类型也有两种方法,第二种创建的是一个对象,和number和string一样,但是布尔使用第二种创建方法有个问题就是,因为第二种创建的是一个对象,所以如果直接用来判断无论是真假都会变成真,就像这样

var b = new Boolean(false)

b == Boolean {false}
!!b == true

因为所有对象转换为布尔值都为真

4、创建一个object

var o = {}
var o = new Object()

对于创建对象来说,两种创建方法得出的对象完全一样

公用属性(原型)

原型

所有对象上都有toString,valueOf这两个函数,但是如果创建一个对象就创建一次这种共有的函数,那是非常占内存的。
所以就将这些对象共有的函数给取出来重新生成一个对象并存在一个地址,这样每创建一个对象将共有函数的地址存进去就可以使每个对象调用其公用属性了,不用浪费去声明重复意义的函数
在对象中存在一个隐藏属性__proto__来储存公用属性的地址,当要调用toString时,首先看对象属性里存不存这个函数,如果不存在就会进入公用属性里面去找,然后调用

//控制台打印
var o1 = {}
undefined
var o2 = new Object()
undefined
o1 === o2
false
o1.toString === o2.toString
true

由此可以看出,不同对象里的公用函数是一样的,这个公用属性就是原型
通过原型这种机制,JavaScript 中的对象从其他对象继承功能特性;这种继承机制与经典的面向对象编程语言的继承机制不同。

原型链

不仅只有object有公用属性,Number、String、Boolean都有各自的共有属性,如果创建一个number类型,其中toFixed函数并没有存在于Obj的公用属性里面,那么它要存在哪里
这就是因为Number也存在自己的公用属性,当使用Number创建一个对象的时候,对象中存在隐藏属性__proto__储存着Number公用属性的地址,而Number的公用属性中也存在着一个隐藏属性__proto__,这个隐藏属性存着的地址是Object的公用属性的地址

var n = new Number(1)
var o1 = new Object()
n.__proto__.__proto__ === o1.__proto__
true

不仅是Number类型是这样,String和Boolean类型中也存在各自的公用属性,而像上面描述的那样,Number对象存在隐藏属性指向Number的公用属性,Number公用属性中存在隐藏属性指向Object的公用属性,像这样像一条链子一样将它们的公用属性串连起来的东西就叫做原型链

__proto__和prototype

我们都知道浏览器有垃圾回收机制,但是当我打开一个页面什么都没有创建时,公用属性作为一个哈希表,如果没有被引用,那么它就将会被回收,而是什么引用的它们呢

Object.prototype

这个就是object的公用属性,也就是原型

var o1 = {}
o1.__proto__ === Object.prototype
true

Number对象也是一样的

var n1 = new Number(1)
n1.__proto__ === Number.prototype
true

由此我们可以推出n1的公用属性的公用属性就是

n1.__proto__.__proto__ === Object.prototype
true

String和Boolean也是和Number一样

var s1 = new String('1')
var b1 = new Boolean(true)

b1.__proto__ === Boolean.prototype
true
s1.__proto__ === String.prototype
true
b1.__proto__.__proto__ === Object.prototype
true
s1.__proto__.__proto__ === Object.prototype
true

声明一个变量,就是一、将哈希整理好,二、__proto__指向公用属性
prototype和__proto__都是对公用属性的引用,区别在于,prototype是防止公用属性被垃圾回收清理,而__proto__是对公用属性的使用
总结来说就是

var 对象 = new 函数()
对象.__proto__ === 函数.prototype//因为 Function 是 Object 的构造函数。

__proto__是对象的属性,prototype是函数的属性
虽然String.prototype的隐藏属性指向

String.prototype.__proto__ === Object.prototype
true

但是Object.prototype的隐藏属性指向null

Object.prototype.__proto__ === null
true
    原文作者:梁广铭
    原文地址: https://segmentfault.com/a/1190000015560503
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞