1、typeof 判断属性
typeof 37 === 'number'; true
typeof "bla" === 'string'; true
instanceof 新方法 要提前定义 更准确
var oStringObject = new String("hello world");
console.log(oStringObject instanceof String); // 输出 "true"
清单 3. instanceof 在继承中关系中的用法
1 2 3 4 5 6 7 8 |
|
2、 . tostring 转换字符串
var boo = new Boolean(true)
document.write(boo.toString())
true
3、Object.keys(obj)
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr));
["0", "1", "2"]
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));
VM245:2 (3) ["2", "7", "100"]
4、.substr
<script type="text/javascript">
var str="Hello world!"
document.write(str.substr(3)
)
</script>
输出:
lo world!
5、.slice
<script type="text/javascript">
var arr = new Array(3)
arr[0] = "George"
arr[1] = "John"
arr[2] = "Thomas"
document.write(arr + "<br />")
document.write(arr.slice(1)
+ "<br />")
document.write(arr)
</script>
输出:
George,John,Thomas
John,Thomas
George,John,Thomas
6、js不能检测接口的回车符,要用后台传<br>即可自动回车 可监听键盘事件 ng
<input class="form-control form-control-sm" id="projectName" type=text
[(ngModel)]="newProjectName"
placeholder="请输入长度小于30的项目名称"
(keyup)="projectNameChanged($event)">
import { Component, OnDestroy, OnInit, ElementRef } from "@angular/core";
export class DashboardComponent implements OnInit, OnDestroy {
constructor(
private el: ElementRef
) {}
projectNameChanged(e){
// if(this.newProjectName.length>30){
this.newProjectName = this.newProjectName.slice(0,30)
}
let keycode = window.event ? e.keyCode : e.which;
if(keycode == 13){//回车键
// this.createProject();
// this.el.nativeElement.querySelector("#close").click();
}
if(keycode == 27){//esc键
// this.el.nativeElement.querySelector("#close").click();
}
}
}
7、深拷贝
递归 >
JSON.parse(JSON.Stringify()) 不能拷贝 constructor 方法 >
Object.assign() 不算深拷贝 也不算浅拷贝 一级拷贝 如果内层还有引用类型 就是浅拷贝了 ... 扩展和 assign >
浅拷贝 如let simpleObj = obj;
for in
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
JSON.stringify
let a=[1,2,3,4],
b=deepClone(a);
a[0]=2;
console.log(a,b);
function deepClone(obj){
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone
}
let a=[0,1,[2,3],4],
b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
首先得明白JSON.stringify()与JSON.parse()的作用,针对你的疑问,我们可以这样理解,前者能将一个对象转为json字符串(基本类型),后者能将json字符串还原成一个对象(引用类型)。
基本类型拷贝是直接在栈内存新开空间,直接复制一份名-值,两者互不影响。
而引用数据类型,比如对象,变量名在栈内存,值在堆内存,拷贝只是拷贝了堆内存提供的指向值的地址,而JSON.stringify()巧就巧在能将一个对象转换成字符串,也就是基本类型,那这里的原理就是先利用JSON.stringify()将对象转变成基本数据类型,然后使用了基本类型的拷贝方式,再利用JSON.parse()将这个字符串还原成一个对象,达到了深拷贝的目的。
JSON.stringify()对对象的转换,避开了只拷贝地址指向,无法直接拷贝值本身的问题,不知道这样说你能否理解。
JSON.stringify()与JSON.parse()的作用还是挺强大的,如果有兴趣,可以看看博主这篇关于这两个方法的小归纳。
8、原型链
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null
8、async
all的用法
Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。我们仍旧使用上面定义好的runAsync1、runAsync2、runAsync3这三个函数,看下面的例子:
-
Promise
-
.all([runAsync1(), runAsync2(), runAsync3()])
-
.then(function(results){
-
console.log(results);
-
});
用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。所以上面代码的输出结果就是: 有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,是不是很酷?有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。
race的用法
all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。race的用法与all一样,我们把上面runAsync1的延时改为1秒来看一下:
-
Promise
-
.race([runAsync1(), runAsync2(), runAsync3()])
-
.then(function(results){
-
console.log(results);
-
});
这三个异步操作同样是并行执行的。结果你应该可以猜到,1秒后runAsync1已经执行完了,此时then里面的就执行了。结果是这样的: 你猜对了吗?不完全,是吧。在then里面的回调开始执行时,runAsync2()和runAsync3()并没有停止,仍旧再执行。于是再过1秒后,输出了他们结束的标志。 这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:
-
//请求某个图片资源
-
function requestImg(){
-
var p = new Promise(function(resolve, reject){
-
var img = new Image();
-
img.onload = function(){
-
resolve(img);
-
}
-
img.src = 'xxxxxx';
-
});
-
return p;
-
}
-
//延时函数,用于给请求计时
-
function timeout(){
-
var p = new Promise(function(resolve, reject){
-
setTimeout(function(){
-
reject('图片请求超时');
-
}, 5000);
-
});
-
return p;
-
}
-
Promise
-
.race([requestImg(), timeout()])
-
.then(function(results){
-
console.log(results);
-
})
-
.catch(function(reason){
-
console.log(reason);
-
});
requestImg函数会异步请求一张图片,我把地址写为"xxxxxx",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。运行结果如下:
9、
使用ES2015前:
el.on('click',function(evt) {
var self = this;
fecch('/api').then(function (res) {
return res.json();
}).then(function (result) {
self.something(result);
//...
})
})
使用ES2015后:
el.on('click',evt=>{
fetch('/api').then(res=>res.json()).then(result=>this.something(result))
})
const arr=[1,2,3];
for(const item of arr){
console.log(item);
}
const Zootopia=[
{name:'Nick',gender:1,species:'Fox'},
{name:'Judy',gender:0,species:'Bunny'}
];
for(const [index,{name,species}] of Zootopia.entries){
console.log(`${index}.Hi,I am ${name},and I am a ${species}`);
}
//0.Hi,I am Nick,and I am a Fox
//1.Hi,I am Judy,and I am a Bunny