22-进阶 JS里的对象

2018-05-30  本文已影响0人  格林姆大师

全局对象---标准叫法 glabol,在浏览器里面也叫 window,也是一个 hash;
每一次浏览器生成时,首先就会生成一个全局对象 (global),这个对象就是window,


image.png

window 的属性分为两种,一种是ECMAscipt规定的;一种是浏览器自己开发实现的,不一定遵从相同的规范。


image.png

接下来主要介绍ECMAscipt规定的属性中的几个很常用的。

  1. Number()
    Number()有两种用法:
var n1 = Number('1')
1
-------------
var n2 =  new Number(1)

console.log(n2)
Number {1}
__proto__: Number
[[PrimitiveValue]]: 1


n2.valueOf()
1
n2.toString()
"1"
(18).toString(16)      //转为16进制后再转换成字符串
"12"

n2与n1的区别在于:内存中存放方式不同。

image.png
然而作为简单类型的 n1,也可以:n1.toString(),为什么作为非 对象 类型的n1 可以使用对象的属性用法???
实际上,作为简单类型的n1 在执行 对象的属性 用法时,JS临时创建了一个 new Number(1),然后这个临时的 对象 执行了属性用法后将结果传递过来了,之后n1.toString()执行结束,临时对象也被销毁。
测试:
var n = 1
n.xxx = 2 //能否执行成功??
2  //执行成功
n.xxx ==??
n.xxx  == undefined  ??

内存图如下:

image.png
temp 做为临时对象,在 n.xxx = 2执行完后销毁,因此后面的n.xxx == undefined
  1. String()
    同上,作为简单类型的 String 也可以使用 object.key 格式的用法;
var s1 = "safefwfwefwef"     //简单类型的声明方式

var s2 = new String(s1)    //作为复杂类型的声明方式
----------------------------------------------------------------------------
typeof s1
"string"
typeof s2
"object"
console.log(s2)

String {"safefwfwefwef"}
0: "s"1: "a"2: "f"3: "e"4: "f"5: "w"6: "f"7: "w"8: "e"9: "f"10: "w"11: "e"12: "f"
length: 13            //作为复杂类型的Number并没有length
__proto__: String
[[PrimitiveValue]]: "safefwfwefwef"

s1[0]
"s"
s2[0]
"s"

String几个方法示例(键值对):

s2.charAt(0) //类似s1[0],获取某个索引对应的字符
"s"
s2.charAt(1)
"a"
s2.charCodeAt(6)     //获取对应索引的Unicode 码,10进制
102
s2.charCodeAt(6).toString(16)   //获取对应索引的Unicode 码,16进制
"66"
"  user name  ".trim()    //去除左右两边的空格
"user name"
s1
"safefwfwefwef"
s1.slice(0,2)
"sa"
s1.slice(0,3)
"saf"
var s3 = "hello"
undefined
s3.replace('e','o')  //生成一个新的,而不是改变原有的
"hollo"
s3
"hello"
  1. boolean
    同上:
var b1 = true
undefined
var b2 = new Boolean(true)

-------------------
console.log(b2)
Boolean {true}
    __proto__: Boolean
      constructor: ƒ Boolean()
      toString: ƒ toString()
      valueOf: ƒ valueOf()
      __proto__: Object
        [[PrimitiveValue]]: false
      [[PrimitiveValue]]: true

注意:

var b3 = false
var b4 = new Boolean(false)

!!b3
false
!!b4
true

4 Object
不同上:两种声明方式效果相同

var o1 = {}

var o2 = new Object()

o1
{}
o2
{}
o1 == o2
false
  1. new Number() 的公用属性(原型):
var n = new Number(22)
console.log(n)
-----------------------------
Number {22}
    __proto__:Number   // new Number() 的公用属性(原型)
        constructor:ƒ Number()
        toExponential:ƒ toExponential()
        toFixed:ƒ toFixed()
        toLocaleString:ƒ toLocaleString()
        toPrecision:ƒ toPrecision()
        toString:ƒ toString()
        valueOf:ƒ valueOf()
        __proto__:Object   // new Object() 的公用属性(原型)
        [[PrimitiveValue]]:0
    [[PrimitiveValue]]:22
image.png
  1. new String() 的公用属性(原型):
var s = new String('hello')
undefined
console.log(s)

String {"hello"}
    0:"h"
    1:"e"
    2:"l"
    3:"l"
    4:"o"
    length:5
    __proto__:String    // new String() 的公用属性(原型)
        anchor:ƒ anchor()
        big:ƒ big()
        blink:ƒ blink()
        bold:
        ƒ bold()
        charAt:ƒ charAt()
        ......
        .....
        ......
        valueOf:ƒ valueOf()
        Symbol(Symbol.iterator):ƒ [Symbol.iterator]()
        __proto__:Object         // new Object() 的公用属性(原型)
        [[PrimitiveValue]]:""
    [[PrimitiveValue]]:"hello"
  1. new Object() 的公用属性(原型):
var o = {}

console.log(o)
 
{}
    __proto__:           // new Object() 的公用属性(原型)
        constructor:ƒ Object()
        hasOwnProperty:ƒ hasOwnProperty()
        isPrototypeOf:ƒ isPrototypeOf()
        propertyIsEnumerable:ƒ propertyIsEnumerable()
        toLocaleString:ƒ toLocaleString()
        toString:ƒ toString()
        valueOf:ƒ valueOf()
        __defineGetter__:ƒ __defineGetter__()
        __defineSetter__:ƒ __defineSetter__()
        __lookupGetter__:ƒ __lookupGetter__()
        __lookupSetter__:ƒ __lookupSetter__()
        get __proto__:ƒ __proto__()
        set __proto__:ƒ __proto__()

n.__proto__.__proto__s.__proto__.__proto__o.__proto__所指向的是 heap 中的同一地址空间。
n.__proto__里有toString,o.__proto__里也有toString,这两个是同一个么???

image.png
那么,所有这些公用属性(原型)在哪???
所有这些公用属性(原型)都是 hash ,那么如果这些 hash 没有被引用的话,就会被垃圾回收掉,那么,是谁在引用 它??
Object.prototype 就是 Object的公用属性(原型)。即Object在引用Object的公用属性(原型);
Object.prototype
---------------------
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
    constructor:ƒ Object()
    hasOwnProperty:ƒ hasOwnProperty()
    isPrototypeOf:ƒ isPrototypeOf()
    propertyIsEnumerable:ƒ propertyIsEnumerable()
    toLocaleString:ƒ toLocaleString()
    toString:ƒ toString()
    valueOf:ƒ valueOf()
    __defineGetter__:ƒ __defineGetter__()
    __defineSetter__:ƒ __defineSetter__()
    __lookupGetter__:ƒ __lookupGetter__()
    __lookupSetter__:ƒ __lookupSetter__()
    get __proto__:ƒ __proto__()
    set __proto__:ƒ __proto__()
------------------------
var o1 = {}
undefined
o1.__proto__ === Object.prototype
true

同理:
Number.prototype 就是 Number的公用属性(原型)。即Number在引用Number的公用属性(原型);
String.prototype 就是 String的公用属性(原型)。即String在引用String的公用属性(原型);
Null.prototype 就是 Null的公用属性(原型)。即Null在引用Null的公用属性(原型);
而且:

var n = new Number(1)
undefined
var s = new String('s')
undefined
var b = new Boolean(false)
undefined
var o = new Object()
undefined
n.__proto__ === Number.prototype
true
s.__proto__ === String.prototype
true
b.__proto__ === Boolean.prototype
true
o.__proto__ === Object.prototype
true
n.__proto__.__proto__ === Object.prototype
true
s.__proto__.__proto__ === Object.prototype
true
b.__proto__.__proto__ === Object.prototype
true
Number.prototype.__proto__ === Object.prototype
true
String.prototype.__proto__ === Object.prototype
true
Boolean.prototype.__proto__ === Object.prototype
true
--------------------
Object.prototype.__proto__
null

关于prototype__proto__的区别:
简单的理解是:prototype是某些特殊的函数作为构造函数时的公用属性(原型)的 key 名;__proto__是由构造函数构造出来的具体的 对象 的公用属性(原型)的 key 名。

上一篇 下一篇

猜你喜欢

热点阅读