面包屑思维模型实战模型错题集结构手册流程手册自我检测专题模块
-
微信小程序前端微信小程序前端易错点收集查看
-
css/less/sass样式控制在开发过程中的一些样式控制bug规避查看
-
tp5开发小程序tp5开发小程序时错误积累查看
-
PHP错题集PHP在实际开发过程中遇到的问题查看
-
MySql数据库使用MySql在实际开发中遇到的错误总结查看
-
TP5错题集积累tp5框架在实际开发过程中遇到的问题查看
-
uni-app爬坑主要用于uni-app项目中遇到的一些问题查看
-
Vue.js易错收集vue.js项目常见错误收集整理查看
-
uni-app开发微信小程序uni-app开发微信小程序的一些爬坑积累查看
-
LinuxLinux在部署、开发、运维时遇见的错误积累查看
-
安全设计常见安全设计查看
-
Redis项目中使用redis的相关错误积累查看
-
前端特效前端特效相关错题集查看
最新博文
-
原型继承
JavaScript类型继承在js中非常重要。
主要记住两操作:(1)继承其他类型的成员属性--call/apply继承this对象;(2)继承其他类型的原型链--prototype+new指定原型指定的内存地址。
一.原型链继承
原型链继承是指定原型对象的额外原型地址。增加其获取更多属性的能力;
但原型链继承不能传入参数实现继承的定制化;
function Show(){ this.name="run"; } function Run(){ this.age="20"; //Run继承了Show,通过原型,形成链条 } Run.prototype=new Show(); var show=new Run(); alert(show.name)//结果:run
二.借用构造函数继承(对象冒充继承)
为了解决引用共享和超类型无法传参的问题,我们采用一种叫借用构造函数的技术,或
者成为对象冒充(伪造对象、经典继承)的技术来解决这两种问题function Box(age){ this.name=['Lee','Jack','Hello'] this.age=age; } function Desk(age){ Box.call(this,age); //对象冒充,给超类型传参 } var desk = new Desk(200); alert(desk.age);//200 alert(desk.name);//['Lee','Jack','Hello'] desk.name.push('AAA'); //添加的新数据,只给 desk alert(desk.name)//['Lee','Jack','Hello','AAA']
三.组合继承(原型链继承+借用构造函数继承)
借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需
要原型链+借用构造函数的模式,这种模式成为组合继承。function Box(age) { this.name = ['Lee', 'Jack', 'Hello'] this.age = age; } Box.prototype.run = function () { return this.name + this.age; }; function Desk(age) { Box.call(this, age); //对象冒充 } Desk.prototype = new Box(); //原型链继承 var desk = new Desk(100); alert(desk.run());
四.原型式继承
这种继承借助原型并基于已有的对象创建新对象,
同时还不必因此创建自定义类型function obj(o) { //传递一个字面量函数 function F() {} //创建一个构造函数 F.prototype = o; //把字面量函数赋值给构造函数的原型 return new F(); //最终返回出实例化的构造函数 } var box = { //字面量对象 name : 'Lee', arr : ['哥哥','妹妹','姐姐'] }; var box1 = obj(box); //传递 alert(box1.name); box1.name = 'Jack'; alert(box1.name); alert(box1.arr); box1.arr.push('父母'); alert(box1.arr); var box2 = obj(box); //传递 alert(box2.name); alert(box2.arr); //引用类型共享了
五.寄生组合式继承
寄生组合式继承解决了两次调用的问题,组合式继承就会有两次调用的情况
基本模型如下:
function object(o) { function F() {} F.prototype = o; return new F(); } function inheritPrototype(subType, superType) { var prototype = object(superType.prototype); //创建对象 prototype.constructor = subType; //增强对象 subType.prototype = prototype; //指定对象 }
阅读更多风口下的猪2020-03-05【JavaScript】
-
原型和原型链
JavaScript原型链是js比较重要的部分,在ES6出现之前,js是没有类这个概念的,但开发过程中很多采用面向对象的方式。js就主要使用类型(可以理解为一个构造函数)来当作类,通过原型和原型链来实现类型的实例化和继承。
要注意虽然现在EMACscrpt已经可以用class,但原型及原型链仍然很重要,其在内存管理方面仍然有很大用处。
一.原型及原型链三角图
可以这样理解:
(1)Person是某个产品零部件的生产体系
(2)Person.prototype就是模具;
(3)constructor是生产线;
(4)p.__proto__就是产品编号和产品信息;产品信息逆向工程就是模具,所以Person.prototype=p.__proto__(其实是两者记录的内存地址相同);
(5)p就是该生产体系所生产的实例产品;
(6)我们在实际生产场景中,为生产出订制化的产品:
会修改模具--通过Person.prototype增加删除修改属性;
会更改原材料做不同品质的产品--通过constructor传参;
会涉及到做出产品和其他产品组装成新产品--不复用继承;
会涉及到将其他产品的模具并入现在的生产体系生产全新的产品--复用继承。
二.原型链
所谓的原型链就是通过__proto__链接的链条,在这个链条上前端元素可以获取后端元素的属性。(__proto__指向内存地址)。
原型与原型链注意的核心问题是“继承”和“共享”,也正是这个实现了前端js的代码模块化管理和内存控制。
三.属性在原型链上的查找
查找一个对象的属性,先在其作用域和作用域链上查找(逐级往上查到全局作用域为止),如过作用域链没有该属性,就会去原型和原型链查找,一直查到本地对象为止。
所以会有以下结果出现:
(1)每个对象都有原型,原型链上的属性数量可能和该对象内部属性数量不等、属性名冲突;
(2)实例对象和原型对象及原型链上对象属性名称冲突时,优先使用对象属性;
阅读更多风口下的猪2020-03-05【JavaScript】
-
new关键字都干了什么
JavaScript实例话对象时,new干了三件事情
(1)创建一个新对象;
(2)将新对象的__proto__指向原型的prototype,获得原型各属性方法的地址;
(3)原型使用call方法,让新对象继承this对象,获得调度原型个属性方法的能力;
即
var obj={};
obj.__proto__=Person.prototype;
Person.call(obj);
阅读更多风口下的猪2020-03-04【JavaScript】
-
apply/call
JavaScriptapply和call两者在作用上是相同的,但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。如
func.call(func1,var1,var2,var3)
对应的 apply 写法为:func.apply(func1,[var1,var2,var3])
。一.“召唤”对象继承this对象
call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
即 出继方.call(继承方)。使继承方继承出继方的this对象。
例如:
function Person1 () { this.name = "person1"; this.sayName = function () { alert(this.name); } } function Person2 () { this.name = "person2"; } var p1= new Person2(); Person1.call(p1); p1.sayName(); //person1
如果传入函数或类,这是要把该函数该类看成对象,即该对象继承了出继方的this对象,而原型被没有继承,其实例的对象还是拥有原来的属性。
var message = "hi"; function class1 () { this.message = "yeah"; } function class2 () { this.message = "hello"; this.sayMessage = function () { alert(this.message); } } class2.call(class1); class1.sayMessage(); // hello class1.message = "msg";
var s1 = new class1();
console.log(s1.message) //"yeah" class1.sayMessage(); //msg二.“召唤”参数
call、apply的第二个参数即是参数
function Person2 ($name,$age,$six) {console.log($name);console.log($age);console.log($six);}var arr=['adfsd','b','c'];Person2.apply(this,arr);三.apply、call的异同
apply和call两者在作用上是相同的,但两者在参数上有区别的。
对于第一个参数意义都一样,
但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。如
func.call(func1,var1,var2,var3)
对应的 apply 写法为:func.apply(func1,[var1,var2,var3])
。
阅读更多风口下的猪2020-03-04【JavaScript】
-
async/await使用promise使异步同步化
JavaScriptasync/await使异步同步化,要避免进入一个误区,即将一个异步函数进行同步化,其结果return函数本身,即通过var test= asyncTest();来捕获异步操作的结果是不行的,只有通过then()操作异步获得结果,实现同步逻辑。
这里以将uni-app的request同步化操作来做为例子
/*封装可捕获其结果的异步函数*/
aysnc getBasicInfo(){
let promise=new Promise((resolve)=>{
uni.request(){
url:'https://example.com/api',
methods:'POST',
data:{
'prosId':this.prosId
},
success:(res)=>{
resolve(res.data)
},
fail:(error)=>{
console.log(error.msg)
}
}
});
let result=await promise.then((res)=>{return res }); //关键代码,await让then使用return有了可能
return result; //return会等到await操作符后面的代码运行后再执行
}/*这里then操作就实现同步操作*/
this.getBasicInfo().then((res)=>{
console.log(res);
console.log('hello,world');
})其实核心要注意几点:
(1)await 会捕获其后异步操作的值;
(2)async函数返回的是一个promise对象;
(3)await操作符只能在async函数里使用。
阅读更多风口下的猪2020-03-04【JavaScript】
-
ES7--await操作符
JavaScriptawait是不能单独使用的,其只能在async中使用,所以是async/await。await 操作符用于等待一个 Promise 对象
async/await是实现异步变成同步的解决方案。
返回值
返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。
eg:
function testAwait(){
console.log("testAwait"); }
async function helloAsync(){
await testAwait();
console.log("helloAsync"); }
helloAsync(); // testAwait
// helloAsyncawait针对所跟不同表达式的处理方式:
- Promise 对象:await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值。
- 非 Promise 对象:直接返回对应的值。
阅读更多风口下的猪2020-03-04【JavaScript】
-
ES7---async函数
JavaScriptasync是ES7才有的异步操作关键字,其和promise、generator有很大关联
async关键字什么一个方法,该方法便成一个异步函数,该函数返回一个Promise对象,即async函数后面可接then()方法处理onFulfilled状态下的逻辑代码
eg:
async function helloAsync(){
return "helloAsync";
}
console.log(helloAsync()) // Promise {<resolved>: "helloAsync"}
helloAsync().then(v=>{
console.log(v); // helloAsync
})
阅读更多风口下的猪2020-03-04【JavaScript】
-
js代码性能耗时计算console.time和console.timeEnd用法
JavaScriptconsole.time
方法是开始计算时间,console.timeEnd
是停止计时,输出脚本执行的时间。// 启动计时器 console.time('testForEach'); // (写一些测试用代码) // 停止计时,输出时间 console.timeEnd('testForEach'); // 4522.303ms
这两个方法中都可以传人一个参数,作为计时器的名称,它的作用是在代码并行运行时分清楚各个计时器。对
console.timeEnd
的调用会立即输出执行总共消耗的时间,单位是毫秒。也可以多个console.timeEnd()一起使用
eg:
console.time("time"); for (var i = 0; i < 50000; i++) { var li = document.createElement("li"); document.querySelector(".wrap").append(li); } console.timeEnd("time"); var a = 10; var b = a + 25; console.log( a); console.log(b); console.timeEnd("time");
阅读更多风口下的猪2020-03-03【JavaScript】
-
array.map()使用场景
JavaScript定义和用法
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
eg:
const arr=['1',‘2’,'3'];
function plusone(item){
let newarr=arr.map(plusone);
console.log(newarr);
}
plusone(); //array['2','3','4']实际开发中有个场景非常适合---接口数据映射
eg:
从接口得到数据 res:
let r = res.map(item => { return { title: item.name, sex: item.sex === 1? '男':item.sex === 0?'女':'保密', age: item.age, avatar: item.img } })
也可以省略 return:
const users=res.items.map(item => ({ url: item.html_url, img: item.avatar_url, name: item.login, }) );
阅读更多风口下的猪2020-03-03【JavaScript】
-
composer Querylist时要注意php环境
爬虫Querylist v4功能和方法要比Querylist v3多很多,且更加符合实际项目的需要。但是在composer时要注意如果此时php环境小于7会安装Querylist v3,所以composer Querylist时要将php调到大于7
阅读更多风口下的猪2020-03-02【爬虫】
-
使用CURL非常慢,甚至取不了数据
thinkphp
阅读更多风口下的猪2020-03-02【thinkphp】