1.编程思想
1.1 面向过程
1.2 面向对象
2 构造函数
3 原型
3.1 原型对象
每一个构造函数都有一个原型对象叫prototype,公共属性和方法写在原型对象上,节约内存
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//1.创建构造函数
function Person(uname, age) {
this.uname = uname;
this.age = age;
}
//构造函数中的公共方法可以挂载在构造函数得原型对象上(函数.prototype.原型名称)
Person.prototype.sayHi = function () {
console.log('hi');
}
Person.prototype.num = 10
//2.生成实例对象
const obj1 = new Person('张三', 18);
const obj2 = new Person('李四', 20);
console.log('obj1.num, obj2.num:');
console.log(obj1.num, obj2.num);
console.log('obj1.sayHi(), obj2.sayHi():');
obj1.sayHi();
obj2.sayHi();
console.log('obj1.sayHi === obj2.sayHi:(返回布尔值)');
console.log(obj1.sayHi === obj2.sayHi);
</script>
</body>
</html>
结果:
3.1.1 原型对象-this指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//1.创建构造函数
function Person(uname, age) {
this.uname = uname;
this.age = age;
}
//构造函数中的公共方法可以挂载在构造函数得原型对象上(函数.prototype.原型名称)
Person.prototype.sayHi = function () {
//构造函数中原型对象中的this指向了实例对象
console.log(this === obj1);//返回Trure
}
//2.生成实例对象
const obj1 = new Person('张三', 18);
const obj2 = new Person('李四', 20);
obj1.sayHi()
</script>
</body>
</html>
3.1.2 案例——(给数组做原型方法)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const arr = [1, 8, 3]
//需求: 给数组拓展方法最大值方法,求和方法
//需求:给数组拓展方法,放在原型对象上(节省内存)
// console.log(Array.prototype
Array.prototype.max = function () {
//构造函数的原型对象 中的this指向实例对象
console.log('调用了', this)//this==arr 输出[1,2,3]
return Math.max(...this)
}
console.log(arr.max())

Array.prototype.sum = function () {
return this.reduce((prev, item) => {
return prev + item
})
}
console.log(arr.sum())
</script>
</body>
</html>
结果:
3.2 constructor属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Person(uname) {
this.name = 'zhangsan';
}
//位置:
console.log(Person.prototype.constructor === Person)//TURUE
console.log(Person.prototype)
//作用:constructor 属性指向构造函数
//场景:
//Person.prototype.fn1=function(){}
//Person.prototype.fn2=function(){}
//Person.prototype.fn3=function(){}
//等价于以下:
Person.prototype = {
constructor: Person,
fn1: function () { },
fn2: function () { },
fn3: function () { }
}
console.log(Person.prototype)
const mc = new Person('mc')
</script>
</body>
</html>
3.3 原型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Person(uname) {
this.uname = uname;
}
const mc = new Person('mc');
//每一个对象都有自己的__proto__(原型),指向构造函数的原型对象(prototype)
console.log(Person.prototype)
console.log(mc.__proto__)//ECMAscript2015将__proto__改成了prototype(规范化)
console.log(mc.__proto__ === Person.prototype)//true
</script>
</body>
</html>
3.4 (构造函数-原型对象-实例对象)三者的关系
示例代码:
function Person(name, age) {
this.name = name;
this.age = age;
}
// 添加一个方法到原型对象
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
// 创建实例对象
const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);
// 访问实例对象的属性和方法
console.log(person1.name); // 输出:Alice
console.log(person2.age); // 输出:30
person1.sayHello(); // 输出:Hello, my name is Alice and I am 25 years old.
person2.sayHello(); // 输出:Hello, my name is Bob and I am 30 years old.
// 检查原型链
console.log(person1.__proto__ === Person.prototype); // 输出:true
console.log(Person.prototype.constructor === Person); // 输出:true
3.5 原型链
3.6 原型链--instanceof运算符
作用:用来检测构造函数.prototype是否存在于实例对象的原型链上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Person(uname) {
this.uname = uname;
}
const mc = new Person('mc');
console.log(mc instanceof Person);//True
console.log(mc instanceof Object);//True
console.log('======')
arr = []
console.log(arr instanceof Array);//True
console.log(arr instanceof Object);//True
</script>
</body>
</html>
3.7 原型继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//需求:使用js完成继承功能
//1.封装=>公共的对象,存储公共属性和方法
const Person = {
eyes: 'everyone has 2 eyes,either i',
eat() {
console.log('我会吃饭');
}
}
function Man() {
}
function Woman() {
}
//2.继承=>让Man和Woman继承person的属性和方法
Man.prototype = Person;
Woman.prototype = Person;
//3.验证 让Man和Woman的实例对象能不能访问eyes和eat方法
const xm = new Man('小明');
console.log(xm);
console.log(xm.eyes);
xm.eat();
const xh = new Woman('小红');
console.log(xh);
console.log(xh.eyes);
xh.eat();
</script>
</body>
3.7.1 原型继承问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//需求:使用js完成继承功能
//1.封装=>公共的对象,存储公共属性和方法
const Person = {
eyes: 'everyone has 2 eyes,either i',
eat() {
console.log('我会吃饭');
}
}
function Man() {
}
function Woman() {
}
//2.继承=>让Man和Woman继承person的属性和方法
Man.prototype = Person;
Woman.prototype = Person;
//4. 问题:我们给man构造函数追加一个新方法=>hejiu
Man.prototype.hejiu = function () {
console.log('我会喝酒');
}
//原本只想追加给小明,但却给所有实例对象添加了=>hejiu这个方法
//原因:小明和小红都同时使用了一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都被影响到(对象不独立)
//3.验证 让Man和Woman的实例对象能不能访问eyes和eat方法
const xm = new Man('小明');
const xh = new Woman('小红');
xm.hejiu();//会
xh.hejiu();//会
</script>
</body>
</html>
3.7.2 原型继承问题的解决
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//需求:使用js完成继承功能
//1.封装=>公共的对象,存储公共属性和方法
//解决1.封装=>公共属性和方法放在一个构造函数中
//构造函数创建的对象是互不影响的
function Person() {
this.eyes = 'solve everyone has 2 eyes,either i'
}
Person.prototype.eat = function () {
console.log(' solve everyone can eat')
}
//解决:创建构造函数
function Man(uname) {
this.uname = uname
}
function Woman(uname) {
this.uname = uname
}
//2.继承=>让Man和Woman继承person的属性和方法
//解决2.继承=>让Man和Woman继承person的属性和方法
Man.prototype = new Person();
Woman.prototype = new Person();
console.log(Man.prototype === Woman.prototype);//False
//4. 问题:我们给man构造函数追加一个新方法=>hejiu
Man.prototype.hejiu = function () {
console.log('我会喝酒');
}
//原本只想追加给小明,但却给所有实例对象添加了=>hejiu这个方法
//原因:小明和小红都同时使用了一个对象,根据引用类型的特点,他们指向同一个对象,修改一个就会都被影响到(对象不独立)
//3.验证 让Man和Woman的实例对象能不能访问eyes和eat方法
const xm = new Man('小明');
const xh = new Woman('小红');
console.log(xm);
console.log(xh);
</script>
</body>
</html>