JS里的对象、原型、原型链

全局对象

ES 规定全局对象为 global(浏览器中的 window 为其全局对象)
window 就是一个哈希表
window 的属性就是全局变量

1.ECMAScript 规定

  • global.parseInt
  • global.parseFloat
  • global.Number
  • global.String
  • global.Boolean
  • global.Object

2.浏览器自加属性(某些浏览器私有的属性)

  • window.alert
  • window.prompt
  • window.comfirm
  • window.console.log
  • window.console.dir
  • window.document(文档 w3c DOM)
  • window.document.createElement
  • window.document.getElementById

简单类型和对象

Number()

1.Number(‘1’)
2.var n = new Number(1)
1 => {valueof(): 1, }
var n1 = 1
var n2 = new Number(1)

见下图

想让类似 var n = 1; n.toString()(虽然 toString 不存在)
就两步,先创建一个临时对象出来temp = new Number(1); temp.toString() 返回 temp 给表达式后将 temp 删掉
所以这就好解释

var n = 1;
n.xxx = 2;
n.xxx // undefined

为什么上面的 n.xxx 为 undefined

String()

搜索 string MDN ,查看常用 api

  • String.trim() 去掉空格
  • String.concat() 连接字符串
  • String.slice() 切片
  • Strng.replace() 替换

Boolean()

var f = false
var f2 = new Boolean(false)

if(f) {console.log(1)}
if(f2) {console.log(2)}
2 // 只打印 2
  1. 5 个 false 值: 0 NaN ‘’ null undefined false
  2. 所有对象都是相当于 true 的值

Object()

// 一般是这样写
var n = {}
// 而不是这样
var n = new object()

公用属性(原型)

在 JS 中,原型是指 原型对象 ,而每个对象都拥有一个原型对象,对象以其原型为模板,从原型来继承方法和属性。而对于原型对象来说,它们也可能拥有原型,也会从中继承其方法和属性,这样的层层递进的关系就是 原型链

通常做法是使用隐藏 key __proto__ 用来指向共有的属性

Object 类型和其他类型如 Number 有如下关系

还有一张图

S —> String
n —> Number
b —> Boolean
o —> Object

Object.prototype Object 的共有属性

var o1 = {}
o1.__proto__ === Object.prototype // true
// 注意
Object.__proto__ === Function.prototype,因为 FunctionObject 的构造函数

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

var s1 = new String('1')
s1.__proto__ === String.prototype // true
s1.__proto__.__proto__ === Object.prototype // true

var b1 = new Boolean(true)
b1.__proto__ === Boolean.prototype // true
b1.__proto__.__proto__ === Object.prototype // true

window 的 prototype

不写代码也有 prototype

总结

var 对象 = new 函数()
对象.__proto__ === 函数.prototype

那么 __proto__prototype 的区别?
前者是对象的属性,后者是函数的属性

比较难懂的地方在哪里呢?

var obj = 函数.prototype
obj.__proto__ === Object.prototype

所以存在

函数.prototype.__proto__ === Object.prototype
var obj2 = 函数
obj2.__proto__ === Function.prototype
函数.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
Function.prototype.__proto__ === Object.prototype

Function 这个类型很奇怪,它既是对象也是函数

所以对于 __proto__prototype 来说

  • 不能断章取义,__proto__prototype 只是两个 key 而已
  • 我们一般研究对象的 __proto__ 和函数的 prototype
  • 对象.__proto__ === 某函数.prototype
  • 如果把函数看成对象,那么 函数.__proto__ === Function.prototype
  • 如果把 Function 看成对象,那么 Function.__proto__ === Function.prototype