全局对象 window
ECMAScript 规定全局对象叫做 global,但是浏览器把 window 作为全局对象(浏览器先存在的)
window 就是一个哈希表,有很多属性。window 的属性就是全局变量。
这些全局变量分为两种:
- 一种是 ECMAScript 规定的
- global.parseInt
- global.parseFloat
- global.Number
- global.String
- global.Boolean
- global.Object
- 一种是浏览器自己加的属性
- window.alert
- window.prompt
- window.comfirm
- window.console.log
- window.console.dir
- window.document
- window.document.createElement
- window.document.getElementById
共有属性-原型-原型链
原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象
- prototype一上来就有
- 把对象共有的属性放在原型里
- 子对象不能改变和删除构造函数的原型属性
//Person.prototype = {} 祖先
Person.prototype.lastName = 'mengfeisi'
Person.prototype.say = function() {
console.log('hahaha')
}
function Person(firstName, age, sex) {
this.firstName = firstName
this.age = age
this.sex = sex
}
var person = new Person()
var person1 = new Person()
var person2 = new Person('小明', 25, '男')
console.log(person.lastName) //mengfeisi
console.log(person1.lastName) //mengfeisi
person1.lastName = 'deng'
console.log(person1.lastName) //deng
console.log(person2.firstName) //小明
console.log(person2.lastName) //mengfeisi
console.log(person.say())
console.log(person1.say())
---------------------------------------
function Person() {}
Person.prototype.name = ''
function Car() {}
Car.prototype.name = 'BMW'
var car = new Car()
console.log(car.constructor) //Car() {}
Car.prototype.constructor = Person
console.log(car.constructor) //Person() {}
console.log(car.name) //BMW
proto
function Person() {}
Person.prototype.name = 'hahaha'
var person = new Person()
console.log(person.__proto__) //{name: 'hahaha', constructor: ƒ}
console.log(person.name) //hahaha
var obj = {
name: 'sunny',
}
person.__proto__ = obj
console.log(person.__proto__) //{name: 'sunny'}
console.log(person.name) //sunny
{
var num = [1, 2, 3, 4]
var num1 = num
num = num.push(5)
console.log(num1) //[1, 2, 3, 4, 5]
}
{
var num = [1, 2, 3, 4]
var num1 = num
num = [1, 1, 1, 1, 1]
console.log(num1) //[1, 2, 3, 4] 更换了地址空间
}
{
function Person() {
//var this = {__proto__:Person.prototype}
}
Person.prototype.name = 'sunny'
var person = new Person() //var this = {__proto__:Person.prototype}
Person.prototype = {
name: 'cherry',
}
console.log(person.name)//sunny 更换了地址空间
}
角色:Object的共有属性区,包装类的共有属性区,对象,
- 对象的的“proto”指向包装类的共有属性区,包装类的prototype也指向包装类的共有属性区
- 包装类的共有属性区中的“proto”指向Object的共有属性区,Object的prototype也指向Object的共有属性区
- Object的共有属性区中的“proto”指向null
- 对象.proto === 函数.prototype
Function
函数.proto === Function.prototype
Function.proto === Function.prototype
原型的作用
function Animal(name) {
this.name = name;
}
Animal.prototype.color = 'white';
var cat1 = new Animal('大毛');
var cat2 = new Animal('二毛');
cat1.color // 'white'
cat2.color // 'white'
原型对象上添加一个color属性,结果,实例对象都共享了该属性
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上
Animal.prototype.color = 'yellow';
cat1.color // "yellow"
cat2.color // "yellow"
实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法。这就是原型对象的特殊之处
如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法
cat1.color = 'black';
cat1.color // 'black'
cat2.color // 'yellow'
Animal.prototype.color // 'yellow'
总结一下,原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象
var object = {}
object.__proto__ === Object.prototype
var fn = function(){}
fn.__proto__ === Function.prototype
fn.__proto__.__proto__ === Object.prototype
var array=[]
array.__proto__ === Array.prototype
array.__proto__.__proto__ === Object.prototype
Function.__proto__ === Function.prototype
Array.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
true.__proto__ === Boolean.prototype
Function.prototype.__proto__ === Object.prototype
对象的原型
原型链
function Father() {
this.name = 'xuming'
this.fortune = {
card1: 'visa',
}
this.num = 100
}
var father = new Father()
Son.prototype = father
function Son() {
this.hobbit = 'smoke'
}
var son = new Son()
//不能修改父亲的属性
console.log(son.name) //xuming
son.name = 'laotouzi'
console.log(son.name) //laotouzi
console.log(father.name) //xuming
//可以修改父亲中的对象的属性
console.log(son.fortune) //{card1: 'visa'}
son.fortune.card2 = 'zhongguo'
son.fortune.card1 = 'visa-son'
console.log(son.fortune) //{card1: 'visa-son', card2: 'zhongguo'}
console.log(father.fortune) //{card1: 'visa-son', card2: 'zhongguo'}
console.log(son.num) //100
son.num++
console.log(son.num) //101 son.num++ ---> son.num = son.num + 1
console.log(father.num) //100
console.log(son)
Object.create(原型)
方法重写
如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,也就是说,所有对象都继承了Object.prototype的属性。这就是所有对象都有valueOf和toString方法的原因,因为这是从Object.prototype继承的
Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是nullObject.getPrototypeOf(Object.prototype) // null
读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”(overriding)
注意,一级级向上,在整个原型链上寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链