延续不断更新。。。
基本范例和援用范例
vue props | Primitive vs Reference Types
基本范例和字面值之间的辨别
基本范例和字面值相称,对象实例和字面值不相称(可用于疾速辨别基本范例和对象实例)
arguments与类数组对象
看着这篇
https://github.com/mqyqingfen…
隐式转换
包装对象
number string boolean这三种原始范例都有对应的包装范例。
str 是个基本范例 是个字符串范例 strObj是个对象范例,而且这个对象范例现实上是string范例对应的包装类
str是一个基本范例,它不是对象,所以不该该有属性和要领,那末我想接见这个基本范例的字符串,它的长度是多少
这就有些奇怪了,它是一个基本范例,怎样会有如许一个.length属性
我们尝试给它像属性一样赋值,赋值是胜利的,然则str.t倒是undefined
现实上,javascript中有一个隐蔽的机制,当string number boolean这三个基本范例被尝试用对象一样运用的时刻,比方接见它的length属性也许给它增添一些属性,当作如许的操纵时刻,javascript会将这些基本范例转化为对应的包装范例对象相当于
new string()
new number()
当完成如许的接见今后,这个暂时的包装对象会被烧毁掉,所以在去接见a.t值是undefined
范例检测
杂类
- 推断对象为 null 也许 undefined
// `null == undefined` 为true
if (variable == null) {
// code
}
- 推断对象是不是有某个属性
if(myObj.hasOwnProperty("<property name>")){
alert("yes, i have that property");
}
// 也许
if("<property name>" in myObj) {
alert("yes, i have that property");
}
范例检测
检测范例的要领有许多:
- typeof
- instanceof
- Object.prototype.toString
- constructor
- duck type
typeof
运算符会返回一个字符串,异常合适函数对象和基本范例的推断
检测对象范例
常常使用 instanceof
,它是基于原型链推断的一个操纵符
instanceof
左操纵数是个对象,假如不是直接返回false
右操纵数必需是函数对象也许函数组织器,假如不是会抛出type error
也许道理:instanceof
会推断左操纵数上的对象的原型链上是不是有右侧这个组织函数的prototype
属性
测试某个值是不是是原生数组、原生函数或正则表达式
function isArray(value) {
return Object.prototype.toString.call(value) == "[object Array]";
}
function isFunction(value) {
return Object.prototype.toString.call(value) == "[object Function]";
}
function isRegExp(value) {
return Object.prototype.toString.call(value) == "[object RegExp]";
}
检测原生JSON对象
Object的toString()
要领不能检测非原生组织函数的组织函数名。因而,开辟人员定义的任何组织函数都将返回[object Object]。有些javascript库会包括相似代码:
var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON) == "[Object JSON]"
在web开辟中能够辨别原生非原生javascript对象异常主要。只要如许才确实晓得某个对象到底有哪些功用。
js 中对象是援用通报, 基本范例是值通报, 经由过程将基本范例包装 (boxing) 能够以援用的体式格局通报
var a = 3;
a = a * 2;
console.log(a); // a = 6
var b = 1, c =2, d = 3;
var arr1 = [b,c,d];
arr1.forEach((item)=>{
item = item * 2;
});
console.log(arr1); //arr1 = [1,2,3];
var arr2 = [{a:1},{a:2},{a:3}];
arr2.forEach((item)=>{
item.a = item.a*2;
});
console.log(arr2); //arr2 = [{a:2},{a:4},{a:6}]
function changeStuff(a, b, c)
{
a = a * 10;
b.item = "changed";
c = {item: "changed"};
}
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num);
console.log(obj1.item);
console.log(obj2.item);
//10
//changed
//unchanged
表达式和运算符
var obj = new Foo()
获得一个组织器的实例obj.x
从组织器的prototype属性上拿到xobj.hasOwnProperty('x')
推断这个属性究竟是这个对象上的照样对象的原型链上的
经由过程__proto__
能够拿到对象的原型,这里这个x是属于对象原型上的属性
语句
块block
注重:es6之前没有块级作用域,有全局作用域和函数作用域,另有eval()作用域
函数作用域
浅谈 js eval作用域
这个代码获得的是 1 而不是 123
假如想让 eval 实行的代码是全局的,那末有几种要领。
这个要领规范浏览器都能够获得 123 而IE6-8则依然是 1
ps: 不引荐运用eval()
说明语句
try catch语句
函数和作用域
函数的返回值是依靠return语句的,假如没有return语句会在代码实行完后返回undefined,这是平常的函数挪用
假如是作为组织器,然后外部运用new挪用,组织器假如没有return语句也许return的是基本范例的话,会将this作为返回
this
JavaScript this
this它本身代表函数运转时自天生的一个内部对象,只能在函数内部运用 ,跟着函数运用场所的差别,this的值会发生变化。
然则有个总准绳:
this指的是挪用函数的谁人对象
函数在差别的挪用下this指向是不一样的
挪用函数对象的apply/call/bind等要领,其作用是转变函数的挪用对象,他们的第一个参数就示意转变后的 挪用这个函数的对象,this指的就是这第一个参数
bind()要领是es5供应的,所以ie9+才有
arguments
arguments是一个类数组的对象,之所以说类数组,是它的原型并非array.prototype
所以它没有join()
slice()
这些数组对象才有的要领
严厉情势下 arguments.callee
是制止运用的
apply/call要领(浏览器)
call()第一个参数传的是想作为this的对象,像上面如许假如不是对象,会转成对象,所以这里的100会被转换成对应的包装类 Number(100)
bind要领
- 经由过程
对象.属性名
这类挪用体式格局(moule.getX()
),假如没有bind影响 这里会返回81 - 我们把
moule.getX
如许的函数对象赋值给getX变量,如许挪用this会指向全局对象 所以这里返回9 - 经由过程bind()要领能够转变函数运转时刻内里对应的this,这里的this再绑定module对象今后,再挪用 效果就是81了
bind有函数柯里化功用
函数柯里化:把一个函数拆分红多个单位
作用域
差别挪用体式格局
差别建立体式格局
函数说明 vs 函数表达式
组织器
闭包
什么是闭包
平常函数
function outer () {
var localVal = 30;
return localVal;
}
outer();//30
关于平常的函数,当函数完毕挪用以后,它的局部变量就能够被开释了,详细开释要取决于渣滓接纳的机制
function outer () {
var localVal = 30;
return function () {
return localVal;
}
}
var func = outer();
func(); //30
关于平常函数,函数挪用返回的时刻,局部变量localval就会被开释了,关于下面这类闭包,localVal是不能被开释的。由于挪用outer()今后返回的是一个匿名函数,这个匿名函数内里依然能够接见表面局部变量 localVal.这类机制就有了闭包的另一个主要的运用场景:让变量值一直保持在内存里(概况往下看)
闭包应当场景
读取函数内部变量
让变量值一直保持在内存里
(延伸局部变量的生命周期,封装私有变量)
img 对象经常常使用于举行数据上报,以下所示:
var report = function( src ){
var img = new Image();
img.src = src;
};
report( 'http://xxx.com/getUserInfo' );
然则经由过程查询背景的纪录我们得知,由于一些低版本浏览器的完成存在 bug,在这些浏览器
下运用 report 函数举行数据上报会丧失 30%摆布的数据,也就是说, report 函数并非每一次
都胜利发起了 HTTP 要求。丧失数据的原因是 img 是 report 函数中的局部变量,当 report 函数的
挪用完毕后, img 局部变量随即被烧毁,而此时也许还没来得及发出 HTTP 要求,所以此次要求
就会丧失掉。
如今我们把 img 变量用闭包关闭起来,便能处理要求丧失的题目:
var report = (function(){
var imgs = [];
return function( src ){
var img = new Image();
imgs.push( img );
img.src = src;
}
})();
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
将代码封装成一个闭包情势,守候时机成熟的时刻再运用
比方完成柯里化和反柯里化
罕见毛病
this 相干拓展
react中this的运用
这里的bind()
是es5中的api
原型链
继续相干
完成继续的体式格局
obj.create()来继续
function Person() {}
function Student() {}
Stduent.prototype = Person.prototype;//这类是毛病的,如许转变Student的同时也转变了Person。比方student 会进修一个学科,然则并非人也会,所以我们不能在改写student的时刻把person也改掉
Student.prototype = new Person(); //我们new Person的时刻获得了一个Person的实例,且这个实例是指向Person.prototype
// var o = new Person 则 o.__proto__ = Person.prototype
//上面这类挪用了Person组织函数完成了继续。然则就是由于挪用了组织函数
Student.prototype = Object.create(Person.prototype);//建立一个空对象,而且对象的原型指向Person.prototype 如许既保证能够继续Person.prototype上的要领,Student.prototype又有本身的空的对象 本身的修正不会影响原型链上的内容
//利用了原型链写 不向上查找的特征
Student.prototype.constructor = Student;
call()/ apply()继续
function Person() { this.x = 1; }
function Student() { Person.apply(this); this.y = 2; }
var s = new Student();
s.x;
s.y;
深拷贝浅拷贝
本质上:简朴的来讲就是,在有指针的状况下,浅拷贝只是增添了一个指针指向已存在的内存,而深拷贝就是增添一个指针而且请求一个新的内存,使这个增添的指针指向这个新的内存,采纳深拷贝的状况下,开释内存的时刻就不会出如今浅拷贝时反复开释统一内存的毛病!
js中深复制和浅复制只针对像 Object, Array 如许的庞杂对象的。简朴来讲,浅复制只复制一层对象的属性,而深复制则递归复制了一切层级。
对象中的拷贝
深拷贝
What is the most efficient way to deep clone an object in JavaScript?
数组中的浅拷贝
下面是一个简朴的浅复制完成:
var obj = { a:1, arr: [2,3] };
var shadowObj = shadowCopy(obj);
function shadowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
由于浅复制只会将对象的各个属性举行顺次复制,并不会举行递归复制,而 JavaScript 存储对象都是存地点的,所以浅复制会致使 obj.arr 和 shadowObj.arr 指向统一块内存地点,也许的示意图以下。
致使的效果就是:
shadowObj.arr[1] = 5;
obj.arr[1] // = 5
而深复制则差别,它不仅将原对象的各个属性逐一复制出去,而且将原对象各个属性所包括的对象也顺次采纳深复制的要领递归复制到新对象上。这就不会存在上面 obj 和 shadowObj 的 arr 属性指向统一个对象的题目。
var obj = { a:1, arr: [1,2] };
var obj2 = deepCopy(obj);
效果以下面的示意图所示:
须要注重的是,假如对象比较大,层级也比较多,深复制会带来性能上的题目。在碰到须要采纳深复制的场景时,能够斟酌有无其他替换的计划。在现实的运用场景中,也是浅复制越发常常使用。
更多能够看这几篇文章
http://www.cnblogs.com/racyil…
http://www.cnblogs.com/guorui…
http://jerryzou.com/posts/div…
OOP
这几篇文章是要看一看的
Javascript 面向对象编程(一):封装
Javascript面向对象编程(二):组织函数的继续
Javascript面向对象编程(三):非组织函数的继续
class
class能够看做是一个语法糖,让对象原型的写法越发清楚。
模仿(参数)重载
在java中我们能够经由过程参数的范例的辨别也许数目的辨别,让一样一个函数名能够依据差别的参数列表的状况来挪用响应的函数。
但在javascript中由因而弱范例的,没有直接的机制完成参数的重载。javacript中函数参数范例是不确定的传入的参数个数也是恣意的,能够经由过程推断现实传入的参数的个数来做模仿的重载
挪用子类要领
我们在完成继续的时刻常常要挪用子类的要领
链式挪用
这里能够看看 jQuery
抽象类
defineProperty(ES5)
线程
JS单线程指的是js主引擎单线程,然则浏览器是多线程的,浏览器内里能够包括UI衬着,HTTP要求,用户点击等线程。当多个事宜触发的时刻,JS会把异步事宜顺次的放入eventloop里等同步事宜实行完以后,再去行列里一个个实行event
eventloop
callback
promise
async/await
https://segmentfault.com/a/11…
拾遗
e.target.value
JavaScript 常常使用要领总结
口试的自信心来源于过硬的基本
参考
《JavaScript高等程序设计》
《你所不晓得的JavaScript》
http://www.cnblogs.com/wangfu…
《js典范实例》