147 lines
3.3 KiB
Markdown
147 lines
3.3 KiB
Markdown
# 20191123
|
||
|
||

|
||
|
||
js 高级
|
||
|
||
```js
|
||
function Person(name, age) {
|
||
this.name = name
|
||
this.age = age
|
||
this.sayHi = () => {
|
||
console.log('你好')
|
||
}
|
||
}
|
||
// 实例化对象,并进行初始化
|
||
let pwr = new Person('张三', 18)
|
||
```
|
||
通过原型解决构造函数的缺点
|
||
|
||
原型的作用:数据共享,节省内存
|
||
|
||
既是属性,又是对象
|
||
```js
|
||
Person.prototype.sayHi = function(){}
|
||
...
|
||
per1.sayHi == per2.sayHi // => true
|
||
```
|
||
|
||
示例对象中有一个属性是`__proto__`也是一个对象,也叫原型对象,是提供给浏览器使用的,不是标准的对象,我们可以在一定情况下使用
|
||
|
||
构造函数中有一个属性prototype,也是一个对象,也叫原型对象,是标准的提供给程序员使用
|
||
|
||
实例对象是通过构造函数创建的
|
||
|
||
构造函数 => Person + prototype属性(指向原型对象)
|
||
|
||
原型对象 => constructor构造器(指向Person) + sayHi()
|
||
|
||
实例对象 => name + age(先用构造函数创建) + __proto__属性(指向的是该构造函数的原型对象即构造函数的prototype属性)
|
||
|
||
面向对象编程示例
|
||
|
||
```js
|
||
// 更新div的颜色
|
||
function ChangeBg(btnId, divId, color){
|
||
this.btnId = document.getElementById(btnId)
|
||
this.divId = document.getElementById(divId)
|
||
this.color = color
|
||
}
|
||
ChangeBg.prototype.init = () => {
|
||
// this 与 that 之争
|
||
let that = this
|
||
this.btnId.onclick = function() {
|
||
that.divId.style.background = that.color
|
||
}
|
||
}
|
||
|
||
// 实例化并初始化
|
||
let cb = new ChangeBg()
|
||
cb.init()
|
||
```
|
||
|
||
```js
|
||
// 第二版
|
||
// 按钮,div。color都是对象
|
||
function ChangeBg(btnObj, dvObj, json) {
|
||
this.btn = btnObj
|
||
this.dv = dvObj
|
||
this.json = json
|
||
}
|
||
|
||
ChangeBg.prototype.init = () =>{
|
||
let that = this
|
||
this.btn.onclick = function() {
|
||
for(let key in tht.json) {
|
||
that.dv.style[key] = that.json[key]
|
||
}
|
||
}
|
||
}
|
||
// 实例化
|
||
btnObj = document.getElementById(btnId)
|
||
divObj = document.getElementById(divId)
|
||
json = {...}
|
||
let cb = new ChangeBg(btnObj, divObj, json)
|
||
```
|
||
|
||
什么的数据需要写在原型中?
|
||
|
||
需要共享的数据写在原型中
|
||
|
||
需要共享的属性,需要共享的方法,都可以写在原型中
|
||
|
||
原型作用:共享数据,节省内存
|
||
|
||
不需要共享的数据,不需要共享属性,不需要共享方法,写在构造函数中
|
||
|
||
```js
|
||
function Person(name, age, sex) {
|
||
this.name = name
|
||
this.age = age
|
||
this.sex = sex
|
||
}
|
||
|
||
// 人的身高都是200
|
||
Person.prototype.height = '200cm'
|
||
// 人的体重都是250kg
|
||
Person.prototype.width = '250KG'
|
||
// 人都爱写代码
|
||
Person.prototype.coding = function(){
|
||
console.log('今天每个人都要写完20000行代码,不写完不准睡觉')
|
||
}
|
||
// 人都爱吃鱼
|
||
Person.prototype.eat = function() {
|
||
console.log('人人都爱吃鱼')
|
||
}
|
||
|
||
// 以上等同于,这种写法会丢失构造器,原型对象的构造器容易被重写
|
||
Person.prototype = {
|
||
// 防止构造器被重写
|
||
constructor: Person,
|
||
...
|
||
}
|
||
|
||
let per = new Person('yingbo', 1, 'niko')
|
||
console.dir(per)
|
||
console.dir(Person)
|
||
```
|
||
|
||
属性的搜索机制
|
||
|
||
实例对象的属性或者方法,先在实例对象中查找,在向实例对象中的原型对象中查找
|
||
|
||
实例对象中的方法可以相互调用
|
||
|
||
原型对象中的方法可以相互访问
|
||
|
||
四大内置对象
|
||
|
||
String
|
||
|
||
Array
|
||
|
||
Date
|
||
|
||
Math
|
||
|
||
内置对象中可以添加原型方法 |