2、new关键字、继承、堆栈、深拷贝、浅拷贝

一、new关键字的底层原理

1、new关键字的作用

  • 实例化一个对象返回一个新对象
  • 让构造函数中的this指向实例化对象

2、new关键字的底层原型

  • var p1 = {} 创建了新对象,开辟内存空间
  • Person.call(p1)通过call方法改变函数Person中的this指向,指向实例兑现p1
  • p1.__proto__==Person.prototype p1的指针指向构造函数原型,地址相同,属性和方法都能继承

二、原型的指向是否可以改变

function Animal() { }
Animal.prototype.name = "小狗"

function Dog() { }
Dog.prototype.color = "金毛"
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 = name
	this.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 = sex
	this.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 = name
    this.age = age
    this.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 = score
    this.study = function () {
        console.log(this.name + "喜欢学习")
    }
//Student构造函数中的this指向实例化对象stu,stu对象有Student属性--------------
//stu==this
    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 = name
    this.work = function () {
        console.log(this.name + "热爱工作");
    }
}
//人的原型
Person.prototype.age = 26
Person.prototype.code = function () {
    console.log(this.name + "喜欢敲代码");
}
//学生的构造函数
function Student(sex) {
    this.sex = sex
    this.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、堆:动态分配的内存,大小也不定,也不会自动释放。里面存放引用类型的值

    image-20240222154456005

五、深拷贝与浅拷贝(引用类型)

  • 基本类型:简单的数据段—栈 传值
  • 引用类型:可能有多个值 传址
    地址(引用、指针)—栈
    值—堆
    栈中的地址指向堆中的值

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}

六、练习

var fun = function () { }
fun.prototype = {
    name: 'peter',
    age: 25
}
var a = new fun();
var b = new fun();
console.log(a.name, b.name);//peter peter
fun.prototype.name = 'jack';
console.log(a.name, b.name);//jack jack
// console.log(a.__proto__ == fun.prototype); true
fun.prototype = {};
// console.log(a.__proto__ == fun.prototype); false  因为fun的原型为空  a的原型指针不变
fun.prototype.name = 'tom';console.log(a.name, b.name);//jack jack
b.constructor.prototype.name = 'kitty';
function A() {}
function B(a) {
    this.a = a;
}
function C(a) {
    if (a) {
        this.a = a;
    }
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a);//1
console.log(new B().a);//undefined
console.log(new C(2).a);//2
console.log(new C(0).a);//1
//方法没有会报错  属性没有 undefined
var F = function () {
}
Object.prototype.a = function () {
    console.log('a()')
}
Function.prototype.b = function () {
    console.log('b()')
}
var f = new F()
f.a()//a()  构造函数没有   F没有原型   Object有
f.b()//报错   构造函数没有    F没有原型  Object没有.b  会报错
F.a()//a() 没构造函数  有原型   Object有
F.b()//b()
var P = function () { }
P.prototype.aaa = function () {
    alert("ddd")
}
var a = new P();
var num = 10;//v ar  num = new Number(10)
console.log(P.__proto__ == Function.prototype);//true
console.log(P == a.constructor);//true
console.log(a.__proto__ == P.prototype);//true
console.log(P.prototype.__proto__ == Object.prototype);//true
console.log(a.prototype);//undefined
console.log(Number.__proto__ == Function.prototype);//true
console.log(Number.prototype == num.__proto__);//true
console.log(Function.__proto__ == Function.prototype);//true
console.log(Function.prototype == P.__proto__);//true
console.log(Function.prototype.__proto__ == Object.prototype);//true
console.log(Object.__proto__ == Function.prototype);//true
console.log(Object.prototype.__proto__ == null);//true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值