原型
原型为了共享公共的成员 prototype
原型: JS为每个构造函数提供一个属性prototype(原型),它的值是一个对象,prototype也叫原型对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 面向过程开发(关注具体实现步骤)
// 面向对象开发(分析涉及的对象,指挥对象完成任务) - 封装、继承、多态
function Cat(name, age) {
this.name = name
this.age = age
// 给实例添加eat方法,将来每一个对象都有这个eat方法,造成空间浪费
// this.eat = function () {
// console.log('猫吃老鼠')
// }
}
// 给Cat原型添加公共的属性或方法,这样所有new出来的实例都可以访问
Cat.prototype.eat = function () {
console.log('猫吃老鼠')
}
Cat.prototype.nation = 'china'
const cat1 = new Cat('加菲猫', 3) // {name: '',age: ,eat}
const cat2 = new Cat('银渐层', 4) // {name: '',age: ,eat() {}}
console.log(cat1.age)
console.log(cat1.nation)
cat1.eat()
cat2.eat()
console.log(cat1.eat === cat2.eat) // true
console.log(Cat.prototype)
console.log(Cat.prototype.constructor === Cat) // true
// function f() {}
// console.log(f.prototype)
</script>
</body>
</html>
constructor属性
constructor属性,原型对象的默认属性->原型对象的构造函数
例如:Array.prototype.constructor === Array
console.log(Array.prototype.constructor === Array) // true
const arr = [ ] // new Object()
console.log(arr.constructor === Array) // true
console.log(arr.constructor === Array.prototype.constructor) // true
console.log(arr.constructor) // 访问arr数组对象的constructor,会到原型去访问
console.log(Object.prototype.constructor) // Object ;
const obj = {}
console.log(obj.constructor) // Object
const obj2 = { a: 1 }
console.log(obj.constructor === obj2.constructor) // true
访问对象成员的原则
访问对象成员的原则: 先查找自己身上有没有,有的话就使用,没有去原型查找
<script>
function Cat(name, age) {
// this.name = name
this.age = age
}
Cat.prototype.eat = function () {
console.log('猫抓老鼠')
}
Cat.prototype.name = '亚洲猫王'
const cat = new Cat('小花', 3) // {name: '小花', age: 3}
// 访问对象成员的原则: 先查找自己身上有没有,有的话就使用,没有去原型查找
console.log(cat.name)
</script>
三者关系
<script>
// 定义构造函数
function Person(name, age) {
this.name = name
this.age = age
}
// 在原型上声明一个方法-say()
Person.prototype.say = function () {
console.log('saying')
}
// 实例化对象
const p1 = new Person('小明', 20)
console.log(p1.name)
p1.say()
// prototype->原型对象 __proto__ 原型
console.log(p1.__proto__) // 每个对象都有一个__proto__属性(非标准属性 -> ES6 标准属性),指向原型对象,它与[[Prototype]]等价
console.log(p1.constructor.prototype.constructor)
console.log([].__proto__) // Array.prototype {constructor: Array,...}
console.log([].__proto__.constructor) // Array
console.log([].constructor) // Array
console.log('123'.constructor) // String
console.log(Array.prototype) // 数组原型定义了很多方法
const arr = [1,2,3]
arr.push(4)
</script>
原型应用
给数组拓展方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 给数组拓展方法
Array.prototype.getSum = function () {
console.log(this) // this 指向getSum调用着->实例对象
let sum = 0
this.forEach(function (item) {
sum += item
})
return sum
}
const arr = [1, 2, 3]
const arr2 = [10, 3, 4]
arr2.getSum()
const res = arr2.getSum()
console.log(res)
</script>
</body>
</html>
原型链
对象访问成员的机制
1 首先查找自身有没有,有就就近原则使用
2 自身没有该成员,通过__proto__找到原型对象,看原型对象上有没有,有就执行
3 假如原型对象上也没有,再找原型对象的__proto__ ,一直找到Object.prototype
4 一直找到Object.prototype,找不到就undefined
<script>
// 定义构造函数
function Person(name, age) {
this.name = name
this.age = age
}
// 在原型上声明一个方法-say()
// Person.prototype.say = function () {
// console.log('saying')
// }
// Person.prototype = {
// constructor: Person,
// say: function () {
// console.log('saying')
// },
// }
// Object.prototype.say = function () {
// console.log('我是Object原型上的say')
// }
// 实例化对象
const p1 = new Person('小明', 20)
// p1.say = function () {
// console.log('自己对象上的say')
// }
console.log(p1.name)
// console.log(p1.say)
p1.say()
console.log(Person.prototype)
</script>
原型链练习
<script>
// 内置构造函数Function 创建函数 函数是Function的实例
function f() {} // new Function()
// f.a = 100
// console.log(f.a)
console.log(f.__proto__ === Function.prototype) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // Object.prototype
console.log([].__proto__.__proto__ === Object.prototype) // true
console.log(Function.__proto__.__proto__ === [].__proto__.__proto__)
// const f = new Function('a', 'b', 'return a + b') // function f(a,b) { return a + b}
// console.log(f)
// console.log(f(3, 4))
</script>
instanceof
1.typeof 检测数据类型
string number boolean
console.log(typeof []) //'object'
console.log(typeof {}) // 'object'
2. 数组原型也提供toString(),自己原型的方法是拼接字符串
console.log(Array.prototype)
console.log([1, 2, 3].toString() // [object Array]
console.log({}.toString()) // [object Object]
3.call调用函数
console.log(Object.prototype.toString.call([]))
4.instanceof 实例对象 instanceof 构造函数
判断构造函数的原型对象是不是在实例对象的原型链上
console.log([] instanceof Array) // true
console.log([] instanceof Object) // true
console.log({} instanceof Array) // false