一、new关键字的底层原理
1、new关键字的作用
- 实例化一个对象返回一个新对象
- 让构造函数中的this指向实例化对象
2、new关键字的底层原型、
- var p1 = {} 创建了新对象,开辟内存空间
Person.call(p1)
通过call方法改变函数Person中的this指向,指向实例兑现p1p1.__proto__==Person.prototype
p1的指针指向构造函数原型,地址相同,属性和方法都能继承
二、原型的指向是否可以改变
function Animal() { }
Animal.prototype.name = "小狗"function Dog() { }
Dog.prototype.coloe = "金毛"
Dog.prototype = new Animal()console.log(Animal.prototype.constructor == Animal)//true
console.log(Dog.prototype.constructor == Dog);//false
console.log(Dog.prototype.constructor == Animal);//true
三、3种继承
- 原型继承、构造方法继承(call方法继承)、拷贝继承
1、原型继承
- 目的:让学生对象(子类)继承人对象(父类)的属性和方法,相当于继承人对象的构造函数和原型中的属性和方法
//1、人的构造函数
function Person(name){this.name = namethis.work = function () {console.log(this.name + "热爱工作")}
}
//2、人的原型
Person.prototype.age = 26
Person.prototype.playCode = function (){console.log(this.name + "喜欢敲代码")
}
//3、学生的构造函数
function Student(sex) {this.sex = sexthis.eat = function () {console.log(this.name + "喜欢吃零食")}
}
//----------------必须要写在子类的原型的上面-----------------
Student.prototype = new Person("小明")//4、学生的原型
Student.prototype.className = "web前端"
Student.prototype.learn = function () {console.log(this.name + "喜欢学习")
}
//
console.log(Student.prototype.constructor == Preson)//true
var stu = new Student("男生")//1、学生构造函数中的属性和方法
console.log(stu.sex)//男生
stu.eat()//小明喜欢吃零食
//2、学生原型中的属性和方法
console.log(stu.className)//web前端
stu.learn()//小明喜欢学习
// 3、人构造函数中的属性和方法
console.log(stu.name)//小明
stu.work()//小明热爱工作
// 4、人原型中的属性和方法
console.log(stu.age)//26
stu.playCode()//小明喜欢敲代码
2、构造继承(call方法继承)
//1、人的构造函数
function Person(name, age) {this.name = namethis.age = agethis.work = function () {console.log(this.name + "热爱工作")}
}
//2、人的原型
Person.prototype.sex = "男生"
Person.prototype.basketball = function () {console.log(this.name + "喜欢打篮球")
}
//3、学生的构造函数
//---------注意----------------
function Student(score, x, y) {this.score = scorethis.study = function () {console.log(this.name + "喜欢学习")}
//---------注意----------------Person.call(this, x, y)
}
Student.prototype = new Person()
//4、学生的原型
Student.prototype.className = "web31"
Student.prototype.playCode = function () {console.log(this.name + "喜欢敲代码");
}
//---------注意----------------
var stu = new Student(100, "小花", 18)
// var p1 = new Person("小花",18)// 1、学生构造函数中的属性和方法
console.log(stu.score)
stu.study(
// 2、学生原型中的属性和方法
console.log(stu.className)
stu.playCode()
// 3、人员构造函数中的属性和方法
console.log(stu.name)
console.log(stu.age)
stu.work()
// 4、人员原型中的属性和方法
console.log(stu.sex)
stu.basketball()
3、拷贝继承
//人的构造函数
function Person(name) {this.name = namethis.work = function () {console.log(this.name + "热爱工作");}
}
//人的原型
Person.prototype.age = 26
Person.prototype.code = function () {console.log(this.name + "喜欢敲代码");
}
//学生的构造函数
function Student(sex) {this.sex = sexthis.eat = function () {console.log(this.name + "喜欢吃零食")}
}
//学生的原型
Student.prototype.className = "web前端"
Student.prototype.study = function () {console.log(this.name + "喜欢学习");
}var stu = new Student("男生")
var p = new Person("小明")
//-------------主要代码主要代码----------
for (x in p) {stu[x] = p[x]
}// 1、学生构造函数中的属性和方法
console.log(stu.sex)//男生
stu.eat()//小明喜欢吃零食
// 2、学生原型中的属性和方法
console.log(stu.className)//web前端
stu.study()//小明喜欢学习
// 3、人员构造函数中的属性和方法
console.log(p.name);//小明
p.work()//小明热爱工作
// 4、人员原型中的属性和方法
console.log(p.age);//26
p.code()//小明喜欢敲代码
四、堆栈
JavaScript的变量存储方式:栈(stack)和堆(heap)
-
1、栈:自动分配内存空间,系统自动释放,里面存放的是基本类型和引用类型的地址
-
2、堆:动态分配的内存,大小也不定,也不会自动释放。里面存放引用类型的值
五、深拷贝与浅拷贝(引用类型)
- 基本类型:简单的数据段—栈 传值
- 引用类型:可能有多个值 传址
地址(引用、指针)—栈
值—堆
栈中的地址指向堆中的值
1、浅拷贝
- 会影响原来的值
数组的浅拷贝
var arr1 = [1,2,3]
var arr2 = arr1
console.log(arr2)//[1,2,3]
arr2.push(4)
console.log(arr2)//[1,2,3,4]
console.log(arr1)//[1,2,3,4]

对象的浅拷贝
var obj1 = {name: "小明",age: 18,
}
var obj2 = obj1
obj2.sex = "男生"
console.log(obj2);//{name: '小明', age: 18, sex: '男生'}
console.log(obj1);//{name: '小明', age: 18, sex: '男生'}
2、深拷贝
- 不会影响原来的值
数组的深拷贝
// 1、for循环
var arr3 = [1,2,3]
var arr4 = []
for(var i = 0;i < arr3.length; i++){arr4.push(arr3[i])
}
console.log(arr4)//[1,2,3]
arr4.push(4)
console.log(arr4)//[1,2,3,4]
console.log(arr3)//[1,2,3]
//2、slice
var arr1 = [1,2,3]
var arr2 = arr1.slice(0)
arr2.push(5)
console.log(arr2);//[1,2,3,5]
console.log(arr1);//[1,2,3]
//3、concat()
var arr1 = [1,2,3]
var arr2 = arr1.concat()
console.log(arr2)//[1,2,3]
arr2.push(6)
console.log(arr2)[1,2,3,6]
console.log(arr1)[1,2,3]
对象的深拷贝
//1、for循环
var obj1 = {x: 1,y: 2,
}
var obj2 ={ }
for(x in obj1) {obj2[x] = obj1[x]
}
console.log(obj2);//{x: 1, y: 2}
obj2.z = 3
console.log(obj2);//{x: 1, y: 2, z: 3}
console.log(obj1)//{x: 1, y: 2}