全局对象 window

ECMAScript 规定全局对象叫做 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
    • window.document.createElement
    • window.document.getElementById

共有属性-原型-原型链

原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象

  • prototype一上来就有
  • 把对象共有的属性放在原型里
  • 子对象不能改变和删除构造函数的原型属性


  1. //Person.prototype = {} 祖先
  2. Person.prototype.lastName = 'mengfeisi'
  3. Person.prototype.say = function() {
  4. console.log('hahaha')
  5. }
  6. function Person(firstName, age, sex) {
  7. this.firstName = firstName
  8. this.age = age
  9. this.sex = sex
  10. }
  11. var person = new Person()
  12. var person1 = new Person()
  13. var person2 = new Person('小明', 25, '男')
  14. console.log(person.lastName) //mengfeisi
  15. console.log(person1.lastName) //mengfeisi
  16. person1.lastName = 'deng'
  17. console.log(person1.lastName) //deng
  18. console.log(person2.firstName) //小明
  19. console.log(person2.lastName) //mengfeisi
  20. console.log(person.say())
  21. console.log(person1.say())
  22. ---------------------------------------
  23. function Person() {}
  24. Person.prototype.name = ''
  25. function Car() {}
  26. Car.prototype.name = 'BMW'
  27. var car = new Car()
  28. console.log(car.constructor) //Car() {}
  29. Car.prototype.constructor = Person
  30. console.log(car.constructor) //Person() {}
  31. console.log(car.name) //BMW

proto

  1. function Person() {}
  2. Person.prototype.name = 'hahaha'
  3. var person = new Person()
  4. console.log(person.__proto__) //{name: 'hahaha', constructor: ƒ}
  5. console.log(person.name) //hahaha
  6. var obj = {
  7. name: 'sunny',
  8. }
  9. person.__proto__ = obj
  10. console.log(person.__proto__) //{name: 'sunny'}
  11. console.log(person.name) //sunny

image.png

  1. {
  2. var num = [1, 2, 3, 4]
  3. var num1 = num
  4. num = num.push(5)
  5. console.log(num1) //[1, 2, 3, 4, 5]
  6. }
  7. {
  8. var num = [1, 2, 3, 4]
  9. var num1 = num
  10. num = [1, 1, 1, 1, 1]
  11. console.log(num1) //[1, 2, 3, 4] 更换了地址空间
  12. }
  13. {
  14. function Person() {
  15. //var this = {__proto__:Person.prototype}
  16. }
  17. Person.prototype.name = 'sunny'
  18. var person = new Person() //var this = {__proto__:Person.prototype}
  19. Person.prototype = {
  20. name: 'cherry',
  21. }
  22. console.log(person.name)//sunny 更换了地址空间
  23. }

角色:Object的共有属性区,包装类的共有属性区,对象,

  • 对象的的“proto”指向包装类的共有属性区,包装类的prototype也指向包装类的共有属性区
  • 包装类的共有属性区中的“proto”指向Object的共有属性区,Object的prototype也指向Object的共有属性区
  • Object的共有属性区中的“proto”指向null
  • 对象.proto === 函数.prototype

Function

函数.proto === Function.prototype

Function.proto === Function.prototype

原型的作用

  1. function Animal(name) {
  2. this.name = name;
  3. }
  4. Animal.prototype.color = 'white';
  5. var cat1 = new Animal('大毛');
  6. var cat2 = new Animal('二毛');
  7. cat1.color // 'white'
  8. cat2.color // 'white'

原型对象上添加一个color属性,结果,实例对象都共享了该属性
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上

  1. Animal.prototype.color = 'yellow';
  2. cat1.color // "yellow"
  3. cat2.color // "yellow"

实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法。这就是原型对象的特殊之处
如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法

  1. cat1.color = 'black';
  2. cat1.color // 'black'
  3. cat2.color // 'yellow'
  4. Animal.prototype.color // 'yellow'

总结一下,原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象

  1. var object = {}
  2. object.__proto__ === Object.prototype
  3. var fn = function(){}
  4. fn.__proto__ === Function.prototype
  5. fn.__proto__.__proto__ === Object.prototype
  6. var array=[]
  7. array.__proto__ === Array.prototype
  8. array.__proto__.__proto__ === Object.prototype
  9. Function.__proto__ === Function.prototype
  10. Array.__proto__ === Function.prototype
  11. Object.__proto__ === Function.prototype
  12. true.__proto__ === Boolean.prototype
  13. Function.prototype.__proto__ === Object.prototype

对象的原型

JavaScript对象 原型与原型链 - 图2

JavaScript对象 原型与原型链 - 图3

原型链

image.png

  1. function Father() {
  2. this.name = 'xuming'
  3. this.fortune = {
  4. card1: 'visa',
  5. }
  6. this.num = 100
  7. }
  8. var father = new Father()
  9. Son.prototype = father
  10. function Son() {
  11. this.hobbit = 'smoke'
  12. }
  13. var son = new Son()
  14. //不能修改父亲的属性
  15. console.log(son.name) //xuming
  16. son.name = 'laotouzi'
  17. console.log(son.name) //laotouzi
  18. console.log(father.name) //xuming
  19. //可以修改父亲中的对象的属性
  20. console.log(son.fortune) //{card1: 'visa'}
  21. son.fortune.card2 = 'zhongguo'
  22. son.fortune.card1 = 'visa-son'
  23. console.log(son.fortune) //{card1: 'visa-son', card2: 'zhongguo'}
  24. console.log(father.fortune) //{card1: 'visa-son', card2: 'zhongguo'}
  25. console.log(son.num) //100
  26. son.num++
  27. console.log(son.num) //101 son.num++ ---> son.num = son.num + 1
  28. console.log(father.num) //100
  29. console.log(son)

image.png

image.png

Object.create(原型)

image.png
image.png

方法重写
image.png

如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,也就是说,所有对象都继承了Object.prototype的属性。这就是所有对象都有valueOf和toString方法的原因,因为这是从Object.prototype继承的
Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是null
Object.getPrototypeOf(Object.prototype) // null

读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding)

注意,一级级向上,在整个原型链上寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链

JavaScript对象 原型与原型链 - 图10

JavaScript对象 原型与原型链 - 图11

JavaScript对象 原型与原型链 - 图12

JavaScript对象 原型与原型链 - 图13

javascript初始化

JavaScript对象 原型与原型链 - 图14

JavaScript对象 原型与原型链 - 图15