时光机

笔记


  • 首页

  • 关于

  • 标签

  • 分类

  • 前端笔记

  • 碎碎念

  • 归档

  • 搜索

Vuex

发表于 2020-05-24 | 更新于 2020-05-25 | 分类于 前端笔记

vuex五个核心概念

  1. state:vuex的基本数据,用来存储变量
  2. getters:从基本数据(state)派生的数据,相当于state的计算属性
  3. mutations:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
  4. actions:和mutation的功能大致相同,不同之处在于 ==》*Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作
  5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
    avatar

简述工作流程

  1. 在 vue 组件里面,通过 dispatch 来触发 actions 提交修改数据的操作。
  2. 然后再通过 actions 的 commit 来触发 mutations 来修改数据。
  3. mutations 接收到 commit 的请求,就会自动通过 Mutate 来修改 state
    (数据中心里面的数据状态)里面的数据。
  4. 最后由 store 触发每一个调用它的组件的更新

辅助函数

  1. mapState: 对state的对象进行二次计算,他可以简化我们代码,这样我们获取cartList,不用写this.$store.state.cartList一大串了,尤其对于我们组件中用到次数挺多的情况下,我们完全可以用mapState来代替。

    1
    2
    3
    4
    5
    6
    7
    import { mapState } from 'vuex'
    export default {
    computed:mapState({
    cartList:state => state.cartList,
    getCartList:'cartList' //或者我们新定义一个参数,接受cartList,这样组件其他地方用到了,我们可以用this.getCartList来获取
    })
    }
  2. mapGetter:我们可以理解成他是和mapState一样,都是对state里面的参数进行计算,并返回相应的值,所以我们平常看到的mapState.mapGetters都是在computed属性里面,但是和mapState有点不同的是,mapState是仅对state里面的参数进行计算并返回,而mapGetters是对state参数派生出的属性进行计算缓存,比如计算state中cartList数组的长度或者对他的参数进行筛选

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import { mapGetters} from 'vuex'
    // getters.js
    export default {
    getCartListLen: state =>{
    return state.cartList.length
    }
    }
    // 组件
    export default {
    computed:{
    mapGetters({
    getLen:'getCartListLen'
    }),
    }
    }
  3. mapMutation:写在methods里面,因为他触发的是方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    import { mapMutations} from 'vuex'

    export default {
    methods:{
    ...mapMutations([
    'add_cart', // 将 `this.add_cart()` 映射为 `this.$store.commit('add_cart')`
    ]),
    }
    }
  4. mapAction

    1
    2
    3
    4
    5
    6
    7
    8
    import { mapActions} from 'vuex'
    export default {
    methods:{
    ...mapActions([
    'add_cart', // 将 `this.add_cart()` 映射为 `this.$store.dispatch('add_cart')`
    ]),
    }
    }

Vue2.x基础知识

发表于 2020-05-24 | 更新于 2020-05-26 | 分类于 前端笔记

vue2.x生命周期

avatar

  • beforeCreate ;   //创建前状态,el和data并未初始化
  • created ;   //创建完毕状态,完成了data数据的初始化,el没有
  • beforeMount ;   //挂载前状态,完成了el和data初始化
  • mounted;   //挂载后状态,完成挂载
  • beforeUpdate ;    //更新前状态
  • updated ;    //更新完成状态
  • beforeDestroy ;    //销毁前状态
  • destroyed ;   //销毁完成状态

1.在beforeCreate和created钩子函数之间的生命周期,在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到在created的时候数据已经和data属性进行绑定。

2.created钩子函数和beforeMount间的生命周期,综合排名优先级:render函数选项 > template选项 > outer HTML。

区别

  • created:html加载完成之前,执行。执行顺序:父组件-子组件
  • mounted:html加载完成后执行。执行顺序:子组件-父组件
  • methods:事件方法执行
  • watch:是去监听一个值的变化,然后执行相对应的函数。
  • computed:是计算属性,有缓存功能,是依赖其它的属性计算所得出最后的值

this指向

发表于 2020-01-14 | 更新于 2020-05-24 | 分类于 前端笔记

This指向规则

This指向分为四种绑定规则:默认绑定、隐式绑定、显式绑定以及关键字new绑定。在ES6之后,又有了箭头函数中的this规则。

实例一

1
2
3
4
5
6
7
8
9
10
function foo() { 
console.log(this.bar);
}
var bar = "bar1";
var o2 = {bar: "bar2", foo: foo};
var o3 = {bar: "bar3", foo: foo};

foo();
o2.foo();
foo.call(o3);

三个函数调用分别输出:”bar1”, ”bar2”, ”bar3”。因此这三者分别是默认绑定、隐式绑定和显式绑定。

实例二

1
2
3
4
5
6
7
8
9
10
11
12
var name = 'Nicolas';
function Person(){
this.name = 'Smiley';
this.sayName=function(){
console.log(this);
console.log(this.name);
};
setTimeout(this.sayName, 0); // 第二次输出
}

var person = new Person();
person.sayName();

第一次输出的是Person, Smiley。第二次输出的结果是window,Nicolas。尽管setTimeout是在构造函数中定义的,但是调用的时候,是在window中调用。SetTimeout等许多之后被触发的事件当中,一定要注意this的指向,这是基于调用点(call stack)的 。

实例三

1
2
3
4
5
6
7
8
9
10
11
function Person() {
this.name = "Smiley";
this.sayName = function(){
console.log(this);
console.log(this.name);
};
}

let person = new Person();
let sayNameCopy = person.sayName;
sayNameCopy();

答案是window和undefined。因为,这个时候符合默认绑定的规则。

实例四

1
2
3
4
5
6
7
8
9
10
function Person() {
this.name = "Smiley";
this.sayName = ()=> {
console.log(this);
console.log(this.name);
};
}

let person = new Person();
person.sayName.call({name: "Nicolas"});

我们只改动了一处:把sayName改为箭头函数。结果则变成了Person和”Smiley”。这是因为箭头函数并没有自己的this,被定义在哪里,this就指向谁,且优先级比显式调用高,因此,this仍指向Person。

实例五

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Person(){
this.age = 0;
setTimeout(function () {
console.log(this.age); // 输出undefined
}, 1000);
}
var p = new Person();


function Person(){
this.age = 10;
setTimeout(()=> {
console.log(this.age); // 输出10
}, 1000);
}
var p = new Person();

在上面没有使用箭头函数的例子当中,setTimeout内部的函数是被global调用的,而global没有age这个属性,因此输出undefined。

第二个例子使用了箭头函数,this就会使用lexical scope中的this,就是Person,因此输出10。

绑定优先级

  1. 箭头函数
  2. 关键字new调
  3. 显式绑定
  4. 隐式绑定
  5. 默认绑定

大同之行

发表于 2019-07-09 | 更新于 2019-07-15 | 分类于 碎碎念

2019.7.6日星期六

1.悬空寺-凯歌火锅-华严寺-九龙壁-鼓楼-凤临阁-城墙

        凌晨四点从北京出发去大同,八点半到达第一站衡山脚下的悬空寺,温度16度,明明是夏天,真的是冷到打哆嗦,游玩一个半小时,开车两小时到达市区酒店,吃了当地有名的凯歌火锅,人均60吃到撑,服务员看我们剩的太多,打包了两盘肉,超级好吃的油条油饼,5块钱可以拼5个油瓶跟5个油条,便宜到不敢相信,吃好回酒店睡了会午觉。

        下午第一站华严寺,因为我们几个人都没带现金,华严寺门票在携程上买好了,到了还要去换票,说是得两个小时之后才能进去,不得不找路人兑换现金,现场买票,下次一定要看清楚。寺院有个500平方米的千佛地宫,采用100吨纯铜打造而成,内供佛祖舍利及千尊佛像,金碧辉煌。

        九龙壁离华严寺很近,走路十多分钟,之前还有门票,现在免费,中国比较有代表性的九龙壁有故宫九龙壁、大同九龙壁和北海九龙壁,被称为中国“三大九龙壁”,虽然去过故宫两次,但是也没注意过。

        凤临阁号称是装潢费超过三个亿,去过大同凤临阁,才理解什么叫“煤老板的奢华”,菜品也不是很贵,烧麦必点。

        鼓楼就在一个十字路口点正中间,在外面观看免费,进楼需要10元门票,最后去了城墙,拿身份证免费进去,当天有个音乐节,人挺多,需要另外收费,我们到那已经快结束了,就在城墙溜达溜达,上去之后还有很多人在上面租自行车骑,吹着小风哼着歌,夜晚的景色还是很撩人。

2.云冈石窟-凉粉-刀削面-买土特产-回京

        云冈石窟离市区还有一定的距离,有公交,打车也不贵,起步价7块,到目的地花了40多,因为是5A景点,有专业的讲解,去了只剩三级讲解员,收费120元,讲解时间大约一小时,要是我们自己肯定只是走马观花看一遍,什么也看不出来,游玩时间四个小时左右,保留最好,最好看的是第五、六窟,一个洞窟雕刻需要27年左右,推荐一个游记https://www.jianshu.com/p/00c201742249?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

        回到市区下午一点多,吃了好吃的凉粉,坐汽车去县城摘杏,第一次看到跟桃一样大的杏,临出发又吃了一碗刀削面,这里多刀削面会加豆腐干,还可以加卤蛋,火腿还有肉丸,这边的特色还有羊杂汤,不知道为啥我会想起北京的卤煮,至今都没想吃。

        这次本来是想随便转转,走哪算哪,没想到成了深度游,跟一群志同道合的出去玩是一种享受!

js数组方法

发表于 2019-06-25 | 更新于 2020-03-10 | 分类于 前端笔记

js常用数组方法

1.concat() 用于连接两个或多个数组。不改变原数组。

1
2
3
4
5
var arr1 = [1,2,3];
var arr2 = [4,5];
var arr3 = arr1.concat(arr2);
console.log(arr1); //[1, 2, 3]
console.log(arr3); //[1, 2, 3, 4, 5]

2.join()用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的,默认使用’,’号分割,不改变原数组。

1
2
3
var arr = [2,3,4];
console.log(arr.join()); //'2,3,4' 长度为5
console.log(arr); //[2, 3, 4]

3.push()向数组的末尾添加一个或多个元素,并返回新的长度。末尾添加,返回的是长度,会改变原数组。

1
2
3
4
var a = [2,3,4];
var b = a.push(5);
console.log(a); //[2,3,4,5]
console.log(b); //4

4.pop()用于删除并返回数组的最后一个元素。返回最后一个元素,会改变原数组。

1
2
3
var arr = [2,3,4];
console.log(arr.pop()); //4
console.log(arr); //[2,3]

5.unshift()向数组的开头添加一个或更多元素,并返回新的长度。返回新长度,改变原数组。

1
2
3
var arr = [2,3,4,5];
console.log(arr.unshift(3,6)); //6
console.log(arr); //[3, 6, 2, 3, 4, 5]

6.shift()把数组的第一个元素从其中删除,并返回第一个元素的值。返回第一个元素,改变原数组。

1
2
3
var arr = [2,3,4];
console.log(arr.shift()); //2
console.log(arr); //[3,4]

7.slice()返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。返回选定的元素,该方法不会修改原数组。

1
2
3
var arr = [2,3,4,5];
console.log(arr.slice(1,3)); //[3,4]
console.log(arr); //[2,3,4,5]

8.splice(index,howmany,item)从数组中添加或删除元素,然后返回被删除的数组元素。 注:index表示从什么位置开始添加或删除数组元素,howmany表示删除的元素数量,如果为0,则表示不删除数组元素,item表示新增的数组元素

1
2
3
4
5
6
var a = [5,6,7,8];
console.log(a.splice(1,0,9)); //[]
console.log(a); // [5, 9, 6, 7, 8]
var b = [5,6,7,8];
console.log(b.splice(1,2,3)); //[6, 7]
console.log(b); //[5, 3, 8]

一个人的韩国冒险

发表于 2019-06-13 | 更新于 2019-06-25 | 分类于 碎碎念

1.签证,淘宝找了一家400/次,五年三次的是800,一周出签。

2.提前一个月买机票,自己观察了四五天的价格,买的不是特价机票,但是也不是很贵,北京直飞首尔,往返两千左右,一定要看好自己所属的航空公司以及行李限重,韩亚航空可以一早值机,国航只能提前三小时,行李一定不能超重,会被重罚。

3.订酒店可以选爱彼邻或者携程的民宿还是有性价比高的民宿,自己英语不是很好,找了个中国房东,可以提供一些帮助。

4.准备转换插头。

5.兑换韩币,中国银行要提前一周预约,工商银行的话,部分网点可以兑换,也需要提前预约,之前换美金在招商银行当场就可以兑换的,在国内没兑换成,去银行多取点现金,可以在仁川机场兑换韩币,ATM或者人工,我是在机场兑换了10万韩币,折合人民币6百多点,扣了手续费,只够基本的交通费,大额一定要在明洞换(只能用现金),那边有很多私人换钱的,随便一家都比银行的汇率好。

6.租wifi,我是在携程环球漫游,网络很给力,电也够用,信用度高可以免押金,一定要看清是否是安检区内取还,我入境安检完才想起来没还Wi-Fi,打电话给客服,派了人过来取,服务很赞。

7.在出境的时候在日上订了一部分东西,出境的免税店东西很全,后悔订的少,其实你预定完,不用付钱,等回来提货的时候再付,不想要的也没事,买的眼精华入境的日上没有两件装,买的单瓶,足足比之前出境贵了一百。

8.在仁川机场的便利店办了tmoney的交通卡,可以坐地铁,机场大巴,公交,卡费四千韩币,充值四万韩币,足够四天的交通费(韩国地铁不用安检)。

9.出行地图,Naver,百度地图,我是两者结合用的。

10.出行地铁,韩国地铁APP。

11.首尔的景点逛几个就好,如果要去景福宫,可以租套韩服,就不需要门票,我是在小红书找了一家,免费做发型,两个小时1万5韩币,老板说晚一会没事,服务超级好。

12.购物的话去乐天,新罗,提前下载好app,看好自己要买的东西,可以网上下单,走的那天去机场取货,我是怕那天超重,所以大件本土的品牌可以当场提货,其他的只能去机场提货,购物的坑太多,数量越多折扣越多,还是代购买的划算,现在代购价格很透明,金卡打折,返点,代购都是靠这个挣点钱,因为自己买的量少,折扣很少,部分东西还不如在国内找代购帮忙买,FILA(斐乐)的鞋子能比国内便宜一半,这是我这次出来买到的最划算的。

13.退税,机场可以自助退税机器,也有人工退税。

14.携程在你出发前几天会给你发条短信,是你这次旅行的管家,有什么不懂的,找不到路,各种突发状况都可以问,这服务对于第一次去韩国玩的人来说超级贴心。

混合式应用开发之Cordova+vue中的问题

发表于 2019-06-03

node 环境升级到 v8^ 以上,node-sass 报错的解决方法

  • 报错:Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 8.x
  • 解决方法: 使用 npm rebuild node-sass,然后在更新一下npm update

Javascript面向对象(下)

发表于 2019-05-26 | 更新于 2019-05-28 | 分类于 前端笔记

什么是包装对象

基本类型都有自己对应的包装对象:String、Number、Boolean

1
2
var str='hello';
str.charAt(0) // 基本类型会找到对应的包装对象类型,然后包装对象把所有的属性和方法给了基本类型,包装对象消失

什么是原型链

实例对象与原型之间的连接,叫做原型链(proto)

面向对象的一些属性和方法

  • hasOwnProperty():看是不是对象自身下面是属性

    1
    2
    3
    4
    5
    var arr=[];
    arr.num=10;
    Array.prototype.num2=20;
    console.log(arr.hasOwnProperty('num') //true
    console.log(arr.hasOwnProperty('num2') //false
  • constructor:查看对象的构造函数

    1. 每个原型都会自动添加constructor属性
    2. for…in 的时候属性是找不到的
    3. 避免修改constructor属性
  • instanceof:运算符,判断对象与构造函数在原型链上是否有关系
  • toString():Object上的方法
    1. 系统对象下的都是自带的,自己写的对象都是通过原型链找Object下的
      1
      2
      3
      4
      5
      var arr=[];
      console.log(arr.toString==Object.prototype.toString) //false
      function Aaa(){}
      var a1=new Aaa();
      console.log(a1.toString==Object.prototype.toString) //true
  1. 把对象转字符串

  2. 进制转换

    1
    2
    var num=255
    console.log(num.toString(16)) //ff
  3. 做类型判断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var arr=[];
    console.log(Object.prototype.toString.call(arr)=='[object Array]') //true

    var arr1=new Date
    console.log(Object.prototype.toString.call(arr1)=='[object Date]') //true

    var arr1=new RegExp
    console.log(Object.prototype.toString.call(arr1)=='[object RegExp]') //true

    var arr1=null
    console.log(Object.prototype.toString.call(arr1)=='[object Null]') //true

    //遇到特殊iframe
    window.onload=function(){
    var oF=document.createElement('iframe');
    document.body.appendChild(oF);
    var ifArray=window.frames[0].Array;
    var arr=new ifArray();
    // 判断是否为数组的三种方法,遇到iframe用toString()判断
    console.log(arr.constructor==Array); //false
    console.log(arr instanceOf Array ); //false
    console.log(Object.prototype.toString.call(arr)=='[object Array]') //true
    }

对象的继承

  1. 什么是继承
    • 在原有对象的基础上,略作修改,得到一个新的对象
    • 不影响原有对象的功能
  2. 如何添加继承

    • 属性:call 调用父类的构造函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function CreatePerson(name,sex){ // 父类
    this.name=name;
    this.sex=sex;
    }
    CreatePerson.prototype.showName=function(){
    console.log(this.name)
    }
    var p1=new CreatePerson('小花','女')
    p1.showName()
    function CreateStar(name,sex,job){ //子类
    CreatePerson.call(this,name,sex); // 继承父类属性
    this.job=job;
    }
    extend(CreateStar.prototype,CreatePerson.prototype) // 继承方法
    var p2=new CreateStar('周杰伦','男','歌手')
    console.log(p2.showName())
    function extend(obj1,obj2){
    for(var attr in obj2){
    obj1[attr]=obj2[attr]
    }
    }
    • 方法:for in (拷贝继承)
    1
    2
    3
    4
    5
    6
    7
    var a={name:'小花'};
    var b={};
    for (var attr in a){
    b[attr]=a[attr]
    }
    b.name='小绿'
    console.log(a.name) // 小花,如果不使用for in做处理,返回小绿(堆栈)

Javascript面向对象(上)

发表于 2019-05-21 | 更新于 2019-05-26 | 分类于 前端笔记

什么是面向对象编程

  • 用对象的思想写代码,就是面向对象编程
  • 一直使用的对象数组Array和时间Date

面向对象编程特点(OOP)

  • 抽象:抓住核心问题
  • 封装:只能通过对象来访问方法
  • 继承:从已有对象上继承出新的方法
  • 多态:多对象的不同形态

对象的组成

  • 方法(行为、操作)
  • 属性

种类

  1. 工厂方式(封装函数)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function createPerson(){
    var obj=new Object() // 原料
    obj.name=name // 加工
    obj.showName=fucntion(){
    alert(this.name)
    }
    return obj // 出厂
    }
    var p1=createPerson('小花').showName()
    var p2=createPerson('小林').showName()
    console.log(p1.showName==p2.showName) //false
  2. 构造函数

  • 当new去调用一个函数:这时候函数中当this就是创建出来当对象,而且函数的返回值直接就是this(隐式返回)
  • new后面的函数叫**构造函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function CreatePerson(name){
    this.name=name
    this.showName=fucntion(){
    alert(this.name)
    }
    }
    var p1=new CreatePerson('小花').showName()
    p1.showName()
    var p2=new CreatePerson('小林').showName()
    p2.showName()
    console.log(p1.showName==p2.showName) //false
  • 构造函数之原型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function CreatePerson(){
    this.name=name
    }
    CreatePerson.prototype.showName=function(){
    alert(this.name)
    }
    var p1=new CreatePerson('小花').showName()
    var p2=new CreatePerson('小林').showName()
    console.log(p1.showName==p2.showName) //true

对象的引用

  • 对象类型:赋值不仅是值的复制,而且也是引用的传递

    1
    2
    3
    4
    5
    var a=[1,2,3]
    var b=a
    b.push(4)
    console.log(b) //[1,2,3,4]
    console.log(a) //[1,2,3,4]
  • 例外

    1
    2
    3
    4
    5
    var a=[1,2,3]
    var b=a
    b=[1,2,3,4]
    console.log(b) //[1,2,3,4]
    console.log(a) //[1,2,3]
  • 比较:对象类型值和引用都相同才为true

    例1

    1
    2
    3
    var a=[1,2,3]
    var b=[1,2,3]
    console.log(a===b) // false

    例2

    1
    2
    3
    var a=[1,2,3]
    var b=a
    console.log(a===b) // true

原型

  • 去改写对象下面公用的方法和属性,让公用的方法或者属性在内存中存一份(提高性能)
  • 原型中方法相当于css中的class,普通方法相当于css中的style
  • prototype 要写在构造函数的下面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var arr=[1,2,3,4]
    Array.prototype.sum=function(){
    var result=0;
    for(var i=0;i<this.length;i++){
    result+=this[i]
    }
    return result
    }
    console.log(arr.sum()) // 10
  • 优先级

    1
    2
    3
    4
    var arr=[];
    arr.number=10
    Array.prototype.number=20;
    console.log(arr.number) // 10 (style优先级高于class)
  • 写法以及使用

    1
    2
    3
    4
    5
    6
    function 构造函数(){
    this.属性
    }
    构造函数.prototype.方法=fucntion(){}
    var 对象1=new 构造函数()
    对象1.方法()

设计模式

发表于 2019-05-16 | 更新于 2020-05-29 | 分类于 前端笔记

工厂模式

注释:解决了创建多个对象的问题,但是没有结解决对象识别的问题(怎样知道一个对象的类型)

1
2
3
4
5
6
7
8
9
10
11
function createPerson(name,age,job){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.job = job;
obj.speak = function(){
console.log(this.name);
};
return obj
}
var person1 = createPerson('panrui',20,'前端工程师')

构造函数模式

注释:没有显示的创建对象,没有返回语句,直接将属性赋给this对象,将Person的实例对象标识为一种特定的类型。缺点:每个方法在每个实例上面都需要重新定义一遍。

1
2
3
4
5
6
7
8
9
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.speak = function(){
console.log(this.name);
};
}
var person2 = new Person('panrui',20,'前端工程师')

原型模式

注意:省略了为构造函数传递初始化参数,结果所有实例享有相同的属性(对于函数实用,但是对于那些基本属性也说的过去,但是对于引用类型的数据就麻烦了)。基本属性我们可以在实例当中添加一个同名属性,这样可以隐藏原型当中的对应的属性,但是引用类型的属性却会导致所有实例共享。

1
2
3
4
5
6
7
8
9
10
function Person(){

}
Person.prototype.name = 'panrui';
Person.prototype.age = 23;
Person.prototype.job = '前端工程师';
Person.prototype.speak = function(){
console.log(this.name)
}
var person3 = new Person()

组合使用构造函数与原型模式

构造函数用于定义实例属性,原型上面定义共享的属性和方法

1
2
3
4
5
6
7
8
9
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype.speak = function(){
console.log(this.name)
}
var person4 = new Person()

动态原型模式

1
2
3
4
5
6
7
8
9
10
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
if(typeof this.speak != "function"){
Person.speak = function(){
console.log(this.name);
};
}
}
123
Alina

Alina

开始,我们以为自己什么都知道。后来发现,其实我们什么都不知道。
21 日志
2 分类
16 标签
RSS
GitHub E-Mail
© 2021 Alina