当我们在JS中打出这样的一段代码时
let Person = {}
console.log(Person)
我们就成功创建了一个名字叫做Person的对象,对象中包含两块内容(属性, 方法),一个只有属性没有方法的对象我们一般称为数据结构。例如下面这样:
let Person = {
"name":"张三",
"age":18
}
console.log(Person.name)
注意,此时我们Person对象里面是没有方法的,有的只是一个名叫name和一个名叫age的属性,此时这个对象我们也可以称为数据结构(只是用来保存数据,而不进行任何操作的对象)。当然我们也可以为对象添加方法,具体操作如下:
let Person = {
"name":"张三",
"age":18,
Printf:function(){
console.log("我的名字是:"+ this.name)
}
}
console.log(Person.name)
Person.Printf()
此时我们为这个对象添加了一个名为Printf的方法。
此时的Person是一个实例对象
实例对象
实例对象有两种创建方式,一种是上面那样,通过直接在{}给定属性和方法来直接进行创建,还有一种是通过new关键字来进行创建。
let Person = {
"name":"张三",
"age":18,
Printf:function(){
console.log("我的名字是:"+ this.name)
}
}
console.log(Person.name)
Person.Printf()
let XMLHTTP = new XMLHttpRequest()
console.log(XMLHTTP)
原型对象
首先要明确一定,在JS中,函数也属于对象,原型对象是通过构造函数来实现的,例如,下面我们创建一个名为Person的原型对象:
function Person(name, age){
this.name = name,
this.age = age
}
let P = new Person("李四", 18)
此时我们便创建一个名为Person的原型对象,可以通过new来创建不同的实例对象,例如P就是通过Person创建的一个实例对象。
关于this指向问题
用最简单的话说,当一个函数被调用时,谁调用的这个方法,this就指向谁,例如下面这样的内容:
function Person(name, age) {
this.name = name;
this.age = age;
this.Printf = function() {
console.log(this); // `this` 将指向调用 `Printf` 的对象
};
}
const P = new Person("张三", 18);
const L = new Person("李四", 19);
L.Printf(); // 输出 L 对象 {name: "李四", age: 19, Printf: f}
P.Printf(); // 输出 P 对象 {name: "张三", age: 18, Printf: f}
this在Person原型中被使用,但是这里this指的并不是原型,而是实例。当我们后面在某个函数中看到this时,要检查这个函数是被那个实例调用的,this指向的就是它。
原型链(__proto__)
当我们创建一个对象(实例对象和原型对象都有这个方法),可以通过__proto__去向上查看它的父亲。例如下面这段代码:
function Person(name, age){
this.name = name
this.age = age
}
P = new Person("张三", 18)
console.log(P.__proto__)
此时我们可以获取到实例对象P的父亲(其实也就是Person这个原型对象),当然我们也可以通过Person.__proto__获取原型对象的父亲,也就是Object对象。
function Person(name, age){
this.name = name
this.age = age
}
P = new Person("张三", 18)
console.log(Person.prototype.__proto__)
我们可以对一个实例对象,逐级使用__proto__来寻找最早的父级对象(也就是最早的原型对象)。
同时,当我们调用一个实例属性或者方法时,如果实例中不存在这个属性或方法,也是通过__proto__逐级向上查找的
prototype
prototype是一个函数才具备的属性,也即是实例对象是没有这个属性的,它用于定义该函数创建的所有实例共享的属性和方法,一般情况下,除了构造方法外,不会再其他方法上使用该属性。通过这个属性,我们可以给原型对象添加更多的属性和方法。
function Person(){
}
function printf(){
console.log(this)
}
Person.prototype.name = "张三"
Person.prototype.printf = printf
P = new Person()
L = new Person()
L.name = "李四"
P.printf()
L.printf()
console.log(P.__proto__ === Person.prototype)