面向第一类简述
透过new 缺省的形式
class的constructor(es6)
class Person{
constructor(name){ //内部结构器
this.name = name
}
}
var person = new Person(tom)
function的形式(es3)
function Person(name){
this.name = name
}
var person = new Person(jack)
关键步骤
全自动内部结构对象全自动增设特性全自动回到第一类透过厂房商业模式
function factory(name){
var obj = new Object()
obj.name = name
return obj
}
关键步骤
全自动构建第一类全自动增设特性全自动回到第一类缺省的缺陷
function Person(name){
this.name = name
this.age = 18
this.sayHello = ()=>{
console.log(hello);
}
}
var person = new Person(jack)
var person1 = new Person(tom)
console.log(person == person1);//false 对应的存储地址不一样
console.log(person.age == person1.age);//true
console.log(person.sayHello == person1.sayHello);//false 函数也是引用数据比较的是地址、
因为上面的俩个sayHello方法不是一个方法 证明每次去new一个第一类的时候对应的sayHello就会 重新在对应的堆上开辟一个内存 如果对应的new的操作很多那么对应的sayHello占用的内存就很大 (效率就低了) 按照我们的思考 sayHello方法做的事情是一样 那么我们其实只需要一个sayHello就满足了 缺省的缺陷 就是里面声明的函数 会在每次new的时候重新开辟内存 解决形式 找一个共享的空间(第一类)(只声明一次) 将这个函数放进去) 那么现在这个共享空间应该属于谁 缺省 这个属于缺省的空间就被称为蓝本蓝本
prototype
概述:prototype 是属于函数的一个空间,她是一个第一类。因为缺省也是函数所以它也具备,而在prototype特性我们称为显示蓝本。
函数的prototype
对应的这个prototype显示是一个第一类,里面具备对应的特性及方法。主要为方法,那么也就是prototype特性上一般存放对应的方法。
缺省的prototype
实例第一类访问对于的prototype上的内容可以透过实例第一类.特性名访问 一般将对应的函数存储在对应prototype上(这个函数只会声明一次)。将函数存储在蓝本,将属 性放在缺省里面。 在prototype里面声明的函数的this指向当前的调用的实例第一类proto
概述
-proto称为隐式蓝本 ,她是属于第一类的一个空间,每个第一类都存在这个空间,那么对应的实例第一类也是一个第一类,所以它也有这个空间,这个空间指向对应的缺省的prototype.
var obj = new Object()
//每个第一类都存在的一个空间 它指向对应的缺省的prototypeconsole.log(obj.__proto__);
//第一类的__proto__指向对应的缺省的prototype
console.log(obj.__proto__ == Object.prototype);
function Person(){
}
var person = new Person()
console.log(person.__proto__ == Person.prototype);
// Person.prototype.sayHello = ()=>{
// }
person.__proto__.sayHello = ()=>{
console.log(hello);
}
person.sayHello()
–proto–的指向问题
–proto–指向对应的缺省的prototype
缺省也是一个第一类 那么它的–proto–指向谁 指向对应的父类的缺省的prototype
Object的–proto–指向null
//指向Person.prototype
console.log(person.__proto__);
//指向缺省的蓝本的蓝本 缺省的蓝本是啥 是一个第一类 Object.prototypeconsole.log(person.__proto__.__proto__);
//指向缺省的蓝本的蓝本 缺省的蓝本是啥 是一个第一类 Object.prototype 的__proto__是null
console.log(person.__proto__.__proto__.__proto__);
蓝本链
概述:
第一类在–proto–上找特性的链式结构被称为蓝本链。
从上面的指向问题第一类在蓝本上找特性的过程为
先找自己的–proto–(对应的缺省的prototype),再找对应的自身缺省的蓝本的–proto–找到父类缺省的蓝本,再找对应的父类的蓝本的–proto–直到找到objcet为止Object的蓝本的–proto–(null)上还找不到回到undefined
注意事项
蓝本链不包含对象赋值第一类赋值的操作是找到这个特性重新增设值没有找到这个特性进行 添加这个特性进行赋值操作总结
缺省的蓝本prototype实例第一类的蓝本–proto–实例第一类的–proto–指向缺省的prototype蓝本链透过对应的第一类的–proto–去找对应的特性 直到找到Object为止蓝本一般上面写函数,可以保证函数只声明一次,对应的特性写在缺省内蓝本上的方法/特性。透过实例第一类.特性名直接访问(平常透过第一类去点的方法都称为蓝本方法)在对应的蓝本上的函数里面的this指向当前调用的实例第一类透过蓝本来实现数组的高阶函数
forEach实现map实现
//数组的蓝本
//在数组的蓝本上添加一个myForEach的方法//在对应的蓝本上的函数里面的this指向当前调用的实例第一类
Array.prototype.myForEach = function(fn){
//遍历
for(let i=0;i<this.length;i++){
fn(this[i],i,this)
}
}
Array.prototype.myMap = function(fn){
let returnArr = []
//遍历
for(let i=0;i<this.length;i++){
returnArr.push(fn(this[i],i,this))
}
return returnArr
}
reduce实现
//回调函数 defaultValue初始值Array.prototype.myReduce = function(fn,defaultValue){
//默认请求 前面的值为第一个开始下标为第二个
let previousValue = this[0]
let index = 1
//如果传了初始值 那么对应的初始值为传入的值 开始的下标从0开始
if(typeof defaultValue != undefined){
previousValue = defaultValue
index = 0
}
//遍历
for(let i=index;i<this.length;i++){
previousValue = fn(previousValue,this[i],i,this)
}
return previousValue
}
面向第一类的三大特性
封装(函数的抽取 特性的抽取)
承继(子类承继父类)
多态(重写 子类重写父类方法)
承继
概述:
子类承继父类的特性和方法(非私有的特性和方法 非静态的方法)
承继的实现
使用extends 关键词实现承继 (es6新增 类的承继)
// es6新增类的承继 extends关键词实现
class Person{
constructor(){
this.name = jack
}
}
class Son extends Person{
constructor(age){
super()
this.age = age
}
}
var son = new Son(18)
console.log(`son`, son);
蓝本链的承继 (覆盖之前蓝本的所有方法 显示的时候不会显示承继来的特性 (在蓝本上重复出现一样的特性))
核心 在子类的蓝本上创建父类的第一类
function Person(){
this.name = jack
}
function Son(age){
this.age = age
}
Son.prototype.say = ()=>{
console.log(`你好`);
}
//蓝本承继
// 将要承继的类放在承继的子类的原型上//蓝本链会覆盖原本蓝本上的私有的方法及特性
Son.prototype = new Person()
var son = new Son(18)
console.log(`son`, son);
console.log(son.name);
// son.say()
第一类冒充 (会显示承继的特性 不能承继蓝本上的方法)
核心在子类中调用父类的缺省 更改this 指向
组合承继(使用蓝本链承继和第一类冒充结合)
组合寄生承继(第一类冒充+蓝本链承继 (创建一个蓝本第一类放在蓝本链上))
第一类冒充
在子类的蓝本上创建父类的蓝本第一类
es6的模块化
模块的思想,将对应的功能代码封装为一个模块(js代码 css代码 html代码)。
想要使用别人就导入,想要给别人用就导出。复用。
模块化的常用的商业模式
amd (在对应的加载之前导入)
cmd (在用的时候导入)
comment.js (基于amd和cmd之上)
es6的模块化的关键词 (想要导入想要导出)
import 导入
export 导出
export的使用
第一种export default (只能声明一次)
// //默认导出只有一个 如果使用export default 导出的可以使用对应的一个名字来接export default {
obj,
str,
say
}
接收
import obj from ./test.js
console.log(obj) //{obj,str,say}
第二种导出
//如果直接使用的对应的export 导出那么必须透过{键}来接export const obj = {
name:
jack,
age:18
}
//如果导出的是值类型 一定要写变量名
export const str =
”
你好世界”
export const say = ()=>{
console.log(hello world);
}
接收
import {obj,str,say} from ./test.js
第三种导出
const name = tom
//第三种导出export {
//只能写变量
name
}
接收
import {name} from ./test.js
import使用
import 名字 from 地址