使用原型的好处
目的:1、节省内存空间,2、实现数据共享
原型链:实例与原型的链条称作 原型链
原型的指向是否可以改变 (可以)
原型对象的constructor属性指向构造函数本身,让学生原型指向人的构造函数。
Student.prototype = new Person("小王", 18);
console.log(Person.prototype.constructor === Person)//true
console.log(Student.prototype.constructor === Student)//false
原型链最终指向? ==是Object构造函数的原型
任何一个对象都有__proto__属性,实例化对象的__proto__属性指向的的构造函数的原型,因为任何一个对象都有__proto__属性,原型也是对象,所以原型也有__proto__属性,原型也有__proto__属性指向哪里呢?
继承:原型继承 构造函数继承 拷贝继承
原型继承
例:
有个动物Animal构造函数,Animal构造函数本身有名字name、体重weight属性,动物Animal的原型中有个吃eat方法,可以吃骨头
还有个狗Dog构造函数,Dog构造函数本身有颜色color属性,狗Dog的原型中有个吃咬人bitePerson方法,可以咬人
还有个哈士奇ErHa构造函数,ErHa构造函数本身有性别sex属性,哈士奇ErHa的原型中有和主人玩palyHost方法,可以和主人玩
要求让实例化的哈士奇的reHa,继承Animal、Dog、ErHa构造函数及原型中所有的属性和方法(请使用原型继承)
function Anm(name,weight){
this.name = name
this.weight = weight
}
Anm.prototype.eat = function(){
console.log("吃骨头")
}
function Dog(color){
this.color = color
}
function ErHa(sex){
this.sex =sex
}
Dog.prototype = new Anm("小黑","50Kg")
ErHa.prototype = new Dog("黑色")
Dog.prototype.bitePerson = function(){
console.log("不咬人")
}
ErHa.prototype.playHost = function(){
console.log("和主人玩")
}
var myDog = new ErHa("公")
console.log(myDog.name)
console.log(myDog.weight)
console.log(myDog.eat())
console.log(myDog.color)
console.log(myDog.bitePerson())
console.log(myDog.sex)
console.log(myDog.playHost())
构造函数继承 不能继承原型上的属性
例
有个动物Animal构造函数,Animal构造函数本身有名字name、体重weight属性、年龄age属性、性别sex属性,以及吃eat方法。
有个猫Cat构造函数,猫Cat构造函数本身有颜色color属性,
要求实例化猫cat对象继承动物Animal构造函数所有的属性和方法(请使用构造函数继承)
function Anm(name,weight,age,sex){
this.name = name
this.weight = weight
this.age = age
this.sex = sex
this.eat = function(){
console.log("吃东西")
}
}
function Cat(color,name,weight,age,sex){
this.color = color
// Anm.call(this,name,weight,age,sex)
// Anm.apply(this,[name,weight,age,sex])
Anm.bind(this,name,weight,age,sex)()
}
var mycat = new Cat("花色","花花","20kg","2","girl")
console.log(mycat.name)
console.log(mycat.color)
console.log(mycat.sex)
console.log(mycat.weight)
console.log(mycat.age)
mycat.eat()
深拷贝继承
例
有个动物animal对象,animal对象本身有名字name、体重weight属性,
有个老虎tiger对象,老虎tiger对象本身有性别sex属性,
要求实例化老虎tiger对象继承动物animal对象所有的属性(请使用拷贝继承)
function Anm(name,weight){
this.name = name
this.weight = weight
}
var animal = new Anm("小王","400kg")
function Tiger(sex){
this.sex = sex
}
var tiger = new Tiger("雄")
for(key in animal){
tiger[key] = animal[key]
}
animal.weight = "500kg"
console.log(tiger.name)
console.log(tiger.weight)
console.log(tiger.sex)
拷贝分为深拷贝和浅拷贝
深拷贝:
基本类型与引用类型最大的区别实际就是 传值与传址 的区别
值传递:基本类型采用的是值传递。
浅拷贝:
传址操作
数组深拷贝:
var arr = [1,2,3]
var arr1 = []
for(var i = 0; i <arr.length; i ++){
arr1.push(arr[i])
对象深拷贝:
var arr = {
'1': 1,
'2': 2,
'3': 3
}
var arr1 = {}
for (key in arr) {
arr1[key] = arr[key]
}
console.log(arr1);
函数中this指向
(1)、普通函数中this指向window
(2)、构造函数中this指向实例对象
(3)、对象的方法中this指向该对象
(4)、事件绑定的方法中this指向绑定元素
(5)、计时器函数中this指向window
(6)、数组的元素是函数中this指向该数组
(7)、原型中this指向构造函数的实例
函数也是对象
一种特殊的对象