js里的对象
全局对象(glablo)window(浏览器下[特例])
winndow的属性
window属性分为ECMAscript规定和浏览器私有两种,此章重点讲解ECMAscript规定的相关属性(函数/对象)
1. 浏览器私有的
//window相当于一个hash,有很多值,其中常见的可以跟用户交互的几个函数.
一般关于浏览器window有关的属性,都可以省去点window
比如window.aleart('hi') === aleart('hi')…等
* window.aleart('hi') --出现弹出框'hi'
* window.prompt('填写') --返回用户输入值
* window.confirm('确定吗') --确认返回true
* window.console.log('hi') -- 打印出'hi'
* document --文档 (js是有 ECMAscript规定,document是遵循DOM规范的 DOM是有W3C规定)
![](https://img.haomeiwen.com/i9611412/d46080502642fc0e.png)
![](https://img.haomeiwen.com/i9611412/c467627665491994.png)
- Document
一切与文档有关的一般都可以操作
2. ECMAscript规定
//已学的几个函数(对象) Api
* Number()
* String()
* Boolean()
* Object()
// setTimeout接受两个参数,一个函数一个时间
* window.setTimeout(function(){
console.log('hi')
} , 3000) ---3秒之后打印出'hi'
![](https://img.haomeiwen.com/i9611412/1c9c5a082ae62cbb.png)
Number()
- 两种用法
1. Number('1') -- 转为字符串
2. var n = new Number(1) --声明一个Number对象,此用法会把1包装成为一个函数即一个对象,这个对象有个valueOf()函数,这个函数会返回1,当然还有其他的函数…
比如我们声明了两个函数 var n1 = 1,var n2 = newNumber(1),内存图图示,栈内存地址1为n1 = 1,地址2栈内存为n2地址ADDR 50,堆内存有一个地址为44的对象,内容是名字为xxx的1,一般这个1访问不到,用valueOf() 就能调用这个原始的1,或者toString(),就能得到1的字符串形式'1'。这就是直接声明一个1和一个newNumber的区别。由于js发明者boss要求要长的像java,才有这种写法,不过,一般这种方式没人用,下面我们介绍js发明者发明的另一个秒招。
![](https://img.haomeiwen.com/i9611412/c6fae8df2f04b286.png)
![](https://img.haomeiwen.com/i9611412/79783f4ee09d481c.png)
![](https://img.haomeiwen.com/i9611412/f5500a14dc87ecd8.png)
![](https://img.haomeiwen.com/i9611412/c7c0d0ff22e2015a.png)
JS之父发明了两种方法,一种给boss看的,另一种var n = 1 此方式被广大程序员所喜欢.这种方式不是对象,没有k,是没有n.toString属性的。JS之父就发明了一个妙计,临时转换对象,首先,n.toString()是不成立的,他的方式就是首先声明一个临时对象 tamp = new Number(n),tamp是n的一个复杂类型的封装,此时n.toString相当于 tamp.toString(),然后把tamp.toString()的值作为n.toString()的值,然后干掉tamp,tamp像没出现过一样,这样我们转换也成功了。所以说我们见到一个普通类型(简单类型)也可以.toString()
![](https://img.haomeiwen.com/i9611412/bc37c1166793a376.png)
![](https://img.haomeiwen.com/i9611412/7d36aa5f473f6d57.png)
![](https://img.haomeiwen.com/i9611412/3707897973207935.png)
![](https://img.haomeiwen.com/i9611412/b9eee285a5b3d1a4.png)
因为作为临时转换,用完就消失了,所以我们获取n.xxx的值是undefined
var n = 1
n.toString() //转换成功之后tamp消失,堆内存内所有的东西一起消失
n.xxx = 2 //重新生成转换,随之tamp和堆内存所有东西消失
n.xxx //所以再获取n.xxx的值是undefined
![](https://img.haomeiwen.com/i9611412/bf6c07475709523c.png)
![](https://img.haomeiwen.com/i9611412/d7f45cfbd7829c9d.png)
String()
String()
跟Number()
用法一样,比如我们生成一个简单的字符串var s = 'sczfc'
和一个复杂的字符串(对象)var s2 = new String(s)
,我们打印s2(conlose.log(s2)
)可以看到复杂对象生成了一个原始的s
和一个hash
,s2[0]
--'s'
,s2[1]
--'c'
,上边有讲JS之父发明了一个临时转换对象,所以var s = 'sczfc' === var s2 = new String('sczfc'),此时都是对象,我们发现生成的hash里边,还多出一些东西,像charAt()这些API~
- *charAt()--就是获取某一个索引对应的字符 *
//charAt()
s2.charAt(0)/s2.charAt(2) === s2[0]/s2[1]
![](https://img.haomeiwen.com/i9611412/664fb1a26b05dcd7.png)
![](https://img.haomeiwen.com/i9611412/30819c2198e2774f.png)
- **charCodeAt(0) --某一个索引对应字符的UNCIDE编码
**
s2.charCodeAt(0)
//115 --第一个字符s的UNCIDE编码是115
'a'.charCodeAt(0)
//97 -- a的十进制是97
'a'.charCodeAt(0).toString(16)
// '61' --a的16进制是 '61'
(100).charCodeAt(16)
// 64 --数字100的16进制是64
-
trim() --去除(裁剪)字符串空格
像用户手误输入字符串的时候前后多打了空格' dzkg '
' ssss '.trim()
/ ''sss'' --获取没有空格的字符串
- concat() --连接两个字符串
var a1 = 'heello'
var a2 = 'world'
a1.concat(a2)
// 'helloworld'
- slice() --切片
var a = 'hello'
a.slice(0.2) --切两片
//'he'
a.slice(0.3) --切三片
//'hel'
…
- replace() --替换
var a = 'hello'
a.replace('e','o')
// 'hollo'
Boolean
如果f为真打印1 ,f2为真就打印2
var f = false
var f2 = new Boolean(false)
if(f){console.log(1)}
if(f2){console.log(2)
// 2 ----f2是一个对象(truey),truey为真,对象都为true
}
Object
对象和对象一般都不会相等的,除非一个对象把栈内存的地址赋给另一个对象
var n1 = { }
var n2 = new{ }
n1 === n2
//false
![](https://img.haomeiwen.com/i9611412/6cd81400fc32e6ee.png)
原型链
一般对象里边都有一个 toString()和valueOf(),比如下图中,四个对象都有这两个属性,很浪费内存,这样我们可以设置一个公用属性。可以禁止浪费内存。这样我们生成一个对象的时候,怎么才能使这个对象指向这个公用属性呢?
![](https://img.haomeiwen.com/i9611412/2da0208d4d3fd3e4.png)
![](https://img.haomeiwen.com/i9611412/58db4532bacf038d.png)
解决方法就是
__proto__
,我们没声明一个新对象,除了对象我们自己赋予的key还有一个隐藏的proto(左右分别两个下划线),proto此时存了一个公用属性的栈内存地址,不如A100,这样我们就能调用公共属性的toString()和valueOf()两个属性了,多个对象也是如此。![](https://img.haomeiwen.com/i9611412/4eae2b66b7644c69.png)
![](https://img.haomeiwen.com/i9611412/f63737eb6888633f.png)
![](https://img.haomeiwen.com/i9611412/9d89ef0cd92cfeb8.png)
像一些复杂的对象,比如Number(),它的公用属性除了toString()和valueOf(),还有toFixed()等,而且他的字符串toString(16),转换16进制,跟公用属性也不相同,它需要单独有一个Number()公用的,它的toString(16)指向自己私有的公用属性,而toString()/valueOf()指向公用的,下面内存图图示。
![](https://img.haomeiwen.com/i9611412/588b6ff230a655ea.png)
prototype是没写任何对象之前浏览器设置好指向自己私有共有属性的,proto是你创建一个对象之后指向共有属性的,他们两个指向的都是自己私有共有属性,浏览器设置好的你不能修改的,而你创建对象之后的proto是可以修改的,总的来说,因为垃圾回收的影响,防止被清除,一个是防止消失的,一个是引用的。
![](https://img.haomeiwen.com/i9611412/d389db638b08008f.png)
![](https://img.haomeiwen.com/i9611412/6018ac8d881637dc.png)
形式表达
一般我们声明一个对象,var后是一个对象object/Object,大小写无所谓,等号后边是一个函数(函数也是对象),是开头大写的Object(对象)
![](https://img.haomeiwen.com/i9611412/5a882b7c2252d6b9.png)
当我们声明一个对象,var 对象 = new 函数('1') ,对象的proto就等价于函数的prototype,因为是String类型原始值是'1',所以1.proto等价于string.prototype,他们都指向一个共有属性
![](https://img.haomeiwen.com/i9611412/353e92957c84083f.png)
公式推论proto和prototype
下图1-2看作一张图,图1中,我们知道任何一个对象的proto等价于一个函数的prototype,我们把函数的prototype当做一个整体,由于它先是一个函数,他的proto等价于Function.prototype(蓝色公式1),这时我们把Function当做一个函数,他的proto等价于Function.prototype(蓝色公式2),由此我们可以推论出它的proto和prototype相互指向对方。
![](https://img.haomeiwen.com/i9611412/bd502dca2b77e181.png)
![](https://img.haomeiwen.com/i9611412/2e395beece69dd09.png)
![](https://img.haomeiwen.com/i9611412/cd474dc62bfff130.png)