原型
function Person(name, age) {
this.name = name
this.age = age
this.sayHi = function () {
return "你好" + this.name
}
}
var student = new Person("小明", 18)
通过构造函数可以创建可以用户对象
每个用户对象中的sayHi方法都是完全一样的
创建多个用户对象会造成内存空间的浪费
要解决这个问题 必须学会原型
1.原型
每个函数都会自动附带一个属性prototype,这个属性的值是一个普通对象
2.实例
通过new产生的对象称之为实例
因为js中的对象都是通过new产生的,可以称js中的所有对象为实例
上面一段代码中的student对象为Person构造函数创建的实例
对象
var obj = { a: 1 }
实际js内部执行
var obj = new Object()
obj.a = 1
数组
var arr = [1, 2, 3]
实际js内部执行
var arr = new Array(1,2,3)
函数
function demo(a, b) {
return a + b
}
实际js内部执行
var demo = new Function("a", "b", "return a + b")
3.隐式类型
每个实例中都有一个特殊的属性__proto__,称之为隐式类型,它指向构造函数的原型,所以
Person.prototype === student.__proto__
原型总结 当访问实例时,先找自身属性,如果自身属性没有,将寻找实例的隐式原型(即构造函数的原型),总结得知开头代码可以改为
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function () {
return "你好" + this.name
}
var student = new Person("小明", 18)
console.log(student.sayHi());
打印结果为:你好小明
this
this只有两种情况
第一种是在全局种使用 this指向window
第二种是在函数中引用,this指向取决于函数如何调用
function Demo() {
console.log(this);
}
调用方式 new
new Demo()
打印结果为空对象
Demo()
打印为 window
通过对象调用
var obj = {
a: 1,
b: 2,
method: function () {
console.log(this)
}
}
obj.method()
打印这个对象
call
function Obj(a) {
console.log(this, a)
}
var arr = [1, 2, 3]
Obj.call(arr, 1)
打印结果为[1,2,3] 1
apply 与call 不同的地方为第二个形参不一样,apply第二个形参需要传数组,除此之外功能相同
function Obj(a, b, c) {
console.log(this, a, b, c)
}
var arr = [1, 2, 3]
Obj.apply(arr, [1, 3, 5])
打印结果为 [ 1, 2, 3 ] 1 3 5
判断对象中的属性是本身就有的 还是在原型上查出的
hasOwnProperty()
Obj.prototype.b = 2
function Obj(a) {
this.a = a
}
var c = new Obj(1)
console.log(c.b);
console.log(c.hasOwnProperty("b"))
console.log(c.hasOwnProperty('a'))
打印结果为:2 false true
判断对象中是否包含该属性(包括原型)
in
function Obj(a) {
this.a = a
}
Obj.prototype.b = 2
var c = new Obj(1)
console.log('a' in c);
console.log('b' in c);
打印结果为 true true