22-进阶 JS里的对象
2018-05-30 本文已影响0人
格林姆大师
-
全局对象window
全局对象---标准叫法 glabol,在浏览器里面也叫 window,也是一个 hash;
每一次浏览器生成时,首先就会生成一个全局对象 (global),这个对象就是window,
image.png
window 的属性分为两种,一种是ECMAscipt规定的;一种是浏览器自己开发实现的,不一定遵从相同的规范。
image.png
接下来主要介绍ECMAscipt规定的属性中的几个很常用的。
- 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的区别在于:内存中存放方式不同。
然而作为简单类型的 n1,也可以:
n1.toString()
,为什么作为非 对象 类型的n1 可以使用对象的属性用法???实际上,作为简单类型的n1 在执行 对象的属性 用法时,JS临时创建了一个 new Number(1),然后这个临时的 对象 执行了属性用法后将结果传递过来了,之后
n1.toString()
执行结束,临时对象也被销毁。测试:
var n = 1
n.xxx = 2 //能否执行成功??
2 //执行成功
n.xxx ==??
n.xxx == undefined ??
内存图如下:
temp 做为临时对象,在
n.xxx = 2
执行完后销毁,因此后面的n.xxx == undefined
。
- 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"
- 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
-
公用属性(原型)
- 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
- 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"
- 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,这两个是同一个么???
那么,所有这些公用属性(原型)在哪???
所有这些公用属性(原型)都是 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 名。