js奇技淫巧

 

 

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

// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例

function Aoo(){}

function Foo(){}

Foo.prototype = new Aoo();//JavaScript 原型继承

 

var foo = new Foo();

console.log(foo instanceof Foo)//true

console.log(foo instanceof Aoo)//true

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这三个函数,看下面的例子:

 
  1. Promise

  2. .all([runAsync1(), runAsync2(), runAsync3()])

  3. .then(function(results){

  4. console.log(results);

  5. });

用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。所以上面代码的输出结果就是:    有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,是不是很酷?有一个场景是很适合用这个的,一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各种资源如图片、flash以及各种静态文件。所有的都加载完后,我们再进行页面的初始化。  

race的用法

all方法的效果实际上是「谁跑的慢,以谁为准执行回调」,那么相对的就有另一个方法「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思。race的用法与all一样,我们把上面runAsync1的延时改为1秒来看一下:

 
  1. Promise

  2. .race([runAsync1(), runAsync2(), runAsync3()])

  3. .then(function(results){

  4. console.log(results);

  5. });

这三个异步操作同样是并行执行的。结果你应该可以猜到,1秒后runAsync1已经执行完了,此时then里面的就执行了。结果是这样的:    你猜对了吗?不完全,是吧。在then里面的回调开始执行时,runAsync2()和runAsync3()并没有停止,仍旧再执行。于是再过1秒后,输出了他们结束的标志。   这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:

 
  1. //请求某个图片资源

  2. function requestImg(){

  3. var p = new Promise(function(resolve, reject){

  4. var img = new Image();

  5. img.onload = function(){

  6. resolve(img);

  7. }

  8. img.src = 'xxxxxx';

  9. });

  10. return p;

  11. }

  12.  
  13. //延时函数,用于给请求计时

  14. function timeout(){

  15. var p = new Promise(function(resolve, reject){

  16. setTimeout(function(){

  17. reject('图片请求超时');

  18. }, 5000);

  19. });

  20. return p;

  21. }

  22.  
  23. Promise

  24. .race([requestImg(), timeout()])

  25. .then(function(results){

  26. console.log(results);

  27. })

  28. .catch(function(reason){

  29. console.log(reason);

  30. });

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值