js学习笔记合集

目录

1、JS基本数据类型中null和undefined区别

2、js有哪八种 数据类型

 3、作用域与作用域链

4、闭包

5、js数据类型检测的方式有哪些?

6、instanceOf操作符的实现原理及实现

7、js 中 typeof  NaN的结果是什么

8、js 中判断数组的方法

 9、js 中操作符什么时候用于字符串的拼接

 10、js 中Object.is () 与比较运算符 === 和 == 的区别

 11、js中如何进行隐式类型转换

 12、 js中的深拷贝和浅拷贝的区别

 13、js中与和或操作符的返回值

 14、 js 中 == 操作符的强制类型转换规则

 15、js中 isNaN 与 Number.isNaN()  的区别

16、es6中的 const 定义的 对象的属性 可以修改吗?

 17、ES6中  let、 const 和 var 之问的用法以及区别

18、js中如何的断一个对象是空对象

19、 ES6中new一个箭头函效会怎么样     --->报错

 20、js 中对原型的理解

21、js中对原型链的理解

22、 js 对原型的修改和重写 

23、for ...of  和 for ... in 的区别

24、js 中如何判断 一个属性 是属于实例对象 还是继承与构造函数

25、js 中bind 和call 、apply 的作用以及他们的区别

26、es6 对  promise 的理解以及他的实例方法

27、什么是回调地狱(多个串联的异步操作)以及如何使用Promise解决

28、ES6中对Promise.all的理解以及应用场景

 29、ES6中Promise.race的用法以及使用场景

30、 ES6中使用Promise封装ajax

31、Js中ajax(Async Javascript and XML)的原理是什么?如何实现

 32、Js中localstorage和sessionStorage的区别


1、JS基本数据类型中null和undefined区别

// 基本数据类型中null和undefined的区别以及应用:

// 都是代表没有值
/*
null表示“没有对象”,  该处不应该有值
undefined表示“缺少值”, 该处应该有值,但是还没有定义
转为数值也不同,null转为数值为e,undefined转为数值NaN(不是一个数字)
*/
console.log(Number(null));
console.log(Number(undefined));
/*
什么时候会有null:
1、作为函数的参数,表示该函数的参数不是对象

2、作为对象原型链的终点
什么时候会出现undefined:
1、变量被声明了。但是没有赋值,就等于undefined.
2、调用函数时,应该提供的参数没有提供,该参数就等于undefined。

3、对象没有赋值的属性,该属性的值为undefined。
4、函数没有返回值时,默认返回undefined。
*/

console.log(object.getPrototypeof(object.prototype));
var a;
console.log(a)

2、js有哪八种 数据类型

// javascript有哪些数据类型,它们的区别? // 总共有八种

// 基本数据类型: string/number/boolean/null/undefined/BigInt/symbo1(代表创建之后独一无二并且不可变的数据类型)

//引用数据类型: object
/* 区别
1、声明变量时的存储分配
基本数据类型 存储在,var a=10
引用数据类型 存储在, var arr=[1,2,3,4,5,...]

2、不同的内存分配机制也带来了不同的访问机制
不可以直接访问堆内存空间的位置以及直接操作堆内存空间,只能操作对象在栈内存中引用地址基本数据类型直接访问到,引用数据类型访问引用地址,根据引用地址找到堆中实体
3、复制变量时的不同
基本数据类型:var a=1,var b=a,将原始值的副本赋值新的变量
引用数据类型:var obj={name:'张三"}, var obj1=obj,将引用地址赋值给新的变量

*/
var a=[1,2,3,4,5];
var b=a;
var c=a[0];
console.log(b);  //[1,2,3,4,5]
console.log(c); //改变数值 1
b[4]=6;
c=7;
console.log(a[4]); //[1,2,3,4,6]
console.log(a[0]); // 1
 

 3、作用域与作用域链

// 全局

// let name= ' 你好啊 '

// 声明变量  js  => 1: let name => 作用域集合中,有继续,没有添加这个name属性  2:执行name= ‘你好啊’ ,在运行时赋值

-------

// console.log(name)  // 变量提升 声明的变量没有赋值,为undefined

// var name=' 你好啊 '

------------------------------------------------------------------------------------

// 局部作用域

function fun(){   

     let name= ' 你好啊 '

     console.log(name) // 你好啊

}

fun ()

--------------------------------------------------------------------------------------

let name2 =' 悟空1'

function fun(){
    console.log(name2)

}
  fun()   //悟空1
全局:name2 fun()  局部:name2

// 作用域: 就是一个规则 用来查找变量

// 作用域链:多层嵌套作用域

//

let d = 4
function fn(){
    let c = 3 + d

    console.log(c)  // 7
    function fn1(){
        let b = 2 + d  // 6

        console.log(b)  // 6
        function fn2() {
           let a = 1
        }

     }

     fun1()

}

console.log(fn())   // fn()没有返回值,默认返回 undefined

-----------------------------------------------------------------------------------

// 面试题

let a =1

let a= 1
function fn1(){
    function fn2(){
        console.log(a)   // fn2 的作用域里没有a ,找上一级 fn1 a=2
     }
     function fn3(){
         let a= 4

         fn2()

     }
      let a= 2    //在 fn2 的作用域里

      return fn3  // 最后执行的是 fn2
 }

let fn = fn1()

fn()  // 返回 fn3

//

//全局  a =1   fn1()

//fn1     fn2     fn3  a=2
//fn2
//fn3

-----------------------------------------------------------

let a= 1
function fn1(){
     function fn3(){
         function fn2(){
             console.log(a)//
         }
        let a   // 没有赋值
        fn2()  执行到这里的时候,内存里面已经有一个没有赋值的a了

        a = 4
    }
    let a= 2

    return fn3()
}
let fn = fn1()

console.log(fn)  // undefined

4、闭包

//概念:

1 函数中返回一个函数

2 函数的声明的作用域和函数使用的作用域不同
//用途:

1 获取私有作用域的中的变量

2 这些变量可以保存到内存中
function a(){
   let n = R  //保存到内存中

   function add(){
      n++ 
      return n

   }
return add
}
let getN = a()
console.log( getN())  // console.log( getN())  //2
 

5、js数据类型检测的方式有哪些?

//  1、typeof()   检测数据类型的运算符  
//  console.log("数值"",typeof 10);                    // 数值  number

//  console.log("布尔" ,typeof true);                  // 布尔 boolean

//  console.log("字符串",typeof"你好");             //  字符串 string

//  console.log("数组"",typeof []);                       //  数组 object     引用类型
//  console.log(""函数"",typeof function O0);      //  函数 function

//  console.log("对象"",typeof 0);                        // 对象  object   引用类型
//  console.log("undefined",typeof undefined);    // undefined  undefined

//  console.log("null"",typeof nul1);                     // null  object   基本数据类型   null为0,被识别为0(所有的值在计算机中是以二进制编码存储,浏览器把前三位为0的识别为object对象)


// 2、instanceof      检测某一个实例是否属于这个类     (不能用来检测 null和 undefined)

可以正确判断对象的类型,内部运行机制  判断他在原型链上能否找到这个类型的原型              
// console.log("数值"",10 instanceof Number);           // 数值  false

// console.log("布尔"",true instanceof Boolean);          // 布尔  false

// console.log("字符串","你好’instanceof String);           // 字符串  false

// console.log("数组"",D]instanceof Array);                     // 数组  true
// console.log("函数"",function O)0instanceof Function);   // 函数 true

// console.log(""对象"",0 instanceof 0bject);                         // 对象 true


// 3、constructor  检测实例和类的关系,从而检测数据类型,引用原来构造该对象的函数

(不能用来检测 null和 undefined)
// console.log(“数值”,(10).constructor === Number);                // 数值itrue

// console.log("布尔"",(true) . constructor === Boolean);           //  布尔 true

// console.log("字符串”,(你好:).constructor === String);            //   字符串true

// console.log("数组"",([]).constructor === Array);                       //    数组ltrue
// console.log("函数" ,(function()0).constructor === Function);     //  函数true

// console.log("对象"",(0).constructor === 0bject);                          // 对象 true

//  4、Object-prototype.tostring.call ()

//  var a=Object.prototype.tostring;


// console.log("数值" , a.cal1(10));                       //  数值 [object Number]

// console.log("布尔"", a.cal1(true));                    //  布尔 [object Boolean]

// console.log("字符串", a.call(你好"));                 //  字符串 [object String]

// console.log("数组", a.cal1([]));                          //  数组 [object Array]
// console.log("函数" , a.call(function()));             //  函数 [object Function]

// console.log(""对象"", a.cal1(0));                       //  对象 [object object]
// console.log("undefined",a.call(undefined));      //  undefined [object undefined ]

// console.log("null",a.cal1(nul1));                        //  null  [object Null]
 

6、instanceOf操作符的实现原理及实现

//  Js中instanceof操作符的实现原理以及实现


//  instanceof 操作符 用于判断 构造函数 的 prototype 属性是否出现在对象的原型链中的任何位置。

console.log(0 instanceof objecty;

// 构造函数  相当于一个类

function Person(name){

      this. name= name

}

let obj= new Person(' 张三 ')

console.log( Object.getPrototypeOf(obj) )        // 

console.log( Object.prototype ) //打印原型

console.log( Object.getPrototypeOf(obj)===Object.prototype )    // true

console.log(obj instanceof Person ):  // true

console.log(obj instanceof Object ):  // true

console.1og(object.getPrototypeof(object.getPrototypeof(obj))===Object.prototype);   // true

--------------------------------------------------------------------------------------

手写实现原型链的实现原理

function instance(left,right){
//   获取对象的原型
let proto = object.getPrototypeof(left);

//  获取构造函数的 prototype  属性

let prototype= right.prototype;
    while(true) {  //判断原型能不能获取到
       if( !proto) {  // 取不到返回 false
           return false
       }
       if(proto===prototype){  // 判断对象的原型和构造函数的原型 相等
           return true
       }

      // 如果没有找到,就继续在原型链上找
      proto = object.getPrototypeOf(proto)
    }

}

7、js 中 typeof  NaN的结果是什么

//   NaN ( not a number ) 不是一个数字 ,表示是否属于number类型的一种状态,是或否,不是确切的值

//   js中 number 数据类型除了浮点型和整数型,还有一个特殊值NaN

 console.log( typeof  NaN )   // Number

var a = ' abc '

console.log( Number(a));

//NaN,表达式中存在不可转化的变量,返回了无效的结果,不是返回确切的值

//  NaN不等于本身,不是确切的值,代表一个范围
console.log(NaN == NaN) ;  // false  // 因为NaN不是一个确切的值
console.log(NaN I== NaN);  // true 

8、js 中判断数组的方法

1 、JS中判断数组的方法


//  通过object.prototype.tostring.call () 做判断;

console.log(Object.prototype.toString.call ( [ ] ) )  //  是字符串 [Object Array ]

console.log(Object.prototype.toString.call ( [ ] ). slice(8, -1) )  //  Array

console.log(Object.prototype.toString.call ( [ ] ). slice(8, -1) === 'Array' )  //true

// 通过原型链 做判断

// 对象的隐式原型等于构造函数的显式原型
console.log([._proto__a === Array.prototype);  


// 通过ES6的 Array.isArray() 做判断

console.log(Array.isArray());

// 通过 instanceof 做判断

console.log( [] instanceof Array);

//  通过Array.prototype.isPrototypeOf 做判断  判断Array是否在传入内容的的原型链上console.log(Array.prototype .isPrototypeof( [] );
 

 9、js 中操作符什么时候用于字符串的拼接

//  js 中 + 操作符什么时候用于字符串拼接
//  如果+操作符其中一个操作数是字符巾(或者通过ToPrimitive操作之后最终得到的字符串),则执行字符串的拼接,否则执行数字加法

var a={nane :”张三"》;     //===>  [object ojbect]
// a.valueof()
// a.tostring()
var b= { age:18 };         //===> [object ojbect]

// b.valueof()
// b.tostring()


var c = 1 ;
console.log( a+c );      //  [object ojbect] 1
console.log( a+b );        // [object ojbect][object ojbect]
console.log(1+1+'23');   // 2+'23'  ===> '223'

console.log(1+'23'+4+5);   // '123' +4+5  ===> '1234' +5 ===>'12345'

 10、js 中Object.is () 与比较运算符 === 和 == 的区别

//  js中object.is() 与 比较操作符 “===“(严格相等运算符) 和”==" (相等运算符) 的区别

//  双等号(==): 如果两边的类型不一致,进行强制类型转换,然后再去进行比较
console.log(1==true);    //  -->1==1 --> true   true被转换为 number 1
console.log(1=='1');       // --> 1==1 --> true

// 三等号(===): 如果两边的类型不一致,不会进行强制类型转换,直接返回false,等型等值console.log(1=== true);   // false
console.log(1==='1') ;       //  false 
console.log(NaN === NaN) ;  // false    实际希望为 true

console.log(+0 === -0) ;     //  true         实际希望为 false

不够严谨,使用es6新增 Object.is () 解决

// Object.is(): 用来判断两个值是否严格相等,处理一些特殊的情况,-0和+9不再相等,两个NaN是相等的

console.log( Object.is(NaN,NaN) );    //  true

console.log( Object.is(+0,-0 ) ) ;        // false

 11、js中如何进行隐式类型转换

 //  js中如何进行隐式类型转换   主要发生在运算符之间

/*
ToPrimitive方法  :  这是Js中每个值隐含的自带的方法,用来将值(无论是基本类型值还是对象)转换为基本类型值 , 如果值为基本类型 , 则直接返回值本身 : 如果值为对象,其看起来大概是这样:
         ToPrimitive( obj , type )
         obj --> 需要转换的对象

         type --> 期望的结果类型
type的值可以为number或者string,默认情况下为number

1、当type为number时规则如下:
        (1) 调用obj的valueof方法,如果为原始值,则返回,否则下一步

        (2) 调用obj的toString方法,如果为原始值,则返回,否则下一步

        (3) 指出TypeError异m
2、当type为string时规则如下:
        (1) 调用obj的tostring方法,如果为原始值,则返回,否则下一步

        (2) 调用obj的valueof方法,如果为原始值,则返回,否则下一步
        (3) 抛出TypeError异常
*/
 

var objToNumber = function (value) {
    return Number(value.valueOf().tostring())
}
console.log(objToNumber(0)=a= 0);   //   -->  0
console.log(objToNumber(0)-sE NaN);//-->NaN

// +操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串:其他情况下两边的变量都会被转换为数字。

// console.log(1 +"23" );     // 123
// console.log(1 + false);    // 1
// console.log('1' + false);  // 1false
// console.log(true + false); // 1

// - 、*、/ 操作运算符会转换为数字

// console.log(25 - "23"");   // 2
// console.log(1 * false);    // 0
// console.log(1 / 'aa');     // NaN

// 对于 == 操作符来说

// console.log(3 == true);    // false
// console.log('0' == false); // true
// console.log('0' == e);     // true

//对于< 和 > 比较符,(字母按照字母的排列顺序进行比较)

// console.log('c' > 'b');   // true
// console.log('de' > 'fg'); // false

//其他情况下,转换为数字再比较

// console.log( '12'< 13);   // true
// console.log(false < -1);  // false  0 > -1

//对象

// var a= {}   // 空对象
// console.log( a > 2);   // false
/*
 转换过程

console.log(a.valueof();           // {}
console.log(a.toString());         // [object Object ]
console.log(Number(a.tostring())); // NaN

*/

 

 12、 js中的深拷贝和浅拷贝的区别

// JS中 深拷贝 和 浅拷贝 的区别

// 主要在于复制出来的新对象和原来的对象是否会互相影响,改一个,另一个也会变
// 浅拷贝 :

// 只是指向被复制的内存地址,如果原地址发生改变,那么浅拷贝出来的对象也会改变

// 新旧对象共享内存,修改其中一个,另一个也会受到影响
// 深拷贝 :

// 在内存中开辟一块新的地址用于存放复制的对象

// 新旧对象不会共享内存,修改其中的一个不会影响另一个
// 浅拷贝:
// 通过 = 直接赋值
 

var obj = { name:"张三", age:18 }

var obj1 = obj;

console.log(obj1);  // { name:张三", age: 18}
cbj1.age = 20;
console.log(obj);   // {name :张三", age: 20}
consolc.log(cbj1);  // {name: "涨三", age: 20}

// 浅拷贝常见的方法  Object.assign() 方法

var obj = {name:"张三",age:18};
var obj1 = Object.assign(obj)
obj1.age = 20;
console.log(obj);   // {name: "涨三", age: 20}
console.log(obj1);  // {name: "涨三", age: 20}

// 深拷贝:

1、通过JSON 对象实现深拷贝
// JSON.stringify : 将js的值(对象或者数组)转为一个SON字符电
// JSON.parse : 用来解析sON字符串,转换为0bject类型
 

var obj = {name:"张三" , age:18);
var obj1 = JSON.parse(soN.stringify(obj));

obj1.age = 20;
console.log(obj);      // {name: "涨三", age: 18}
console.log(obj1);    // {name: "涨三", age: 20}

2、使用扩展运算符实现深拷贝

var obj = {name:"张三" , age:18);
var obj1 = {...obj,age:20}

console.log(obj);      // {name: "涨三", age: 18}
console.log(obj1);    // {name: "涨三", age: 20}

 13、js中与和或操作符的返回值

// js中 && (与) 和 ||(或) 操作符的返回值
//  首先对第一个操作数进行条件判断,如果不是布尔值,就先强制转换为布尔类型,然后进行条件判断

//  || (或)
console.log1 ll 2);  //-->1(真),如果第一个操作数为真,返回第一个操作数的值

console.log(0 ll 2); //-->2(真),如果第一个操作数为假,返回第二个操作数的值

// &&(与)
console.log(1 && 0); //-->0(假),如果第一个操作数为真,返回第二个操作数的值console.log(e && 2);  //-->0(假),如果第一个操作数为假,返回第一个操作数的值

// || 和 && 不是返回条件判断的结果返回它们其中一个操作数的值

 14、 js 中 == 操作符的强制类型转换规则

//  js 中==操作符的强制类型转换规定
// 首先判断两者的类型是否相同,如果不相同会进行类型转换,相同的话就比较大小1/转换情况:

//  1、字符串和数字之间的相等比较,将字符串转换为数字之后再进行比较大小

       1== '1'  --> 1 == 1 -->true


//  2、其他类型和布尔类型之间的相等比较,先将布尔值转换为数字后,再应用其他规则进行比较

      true == '1'   --> 1=='1'  --> 1==1 --> true


//  3、nul1和undefined之间的相等比较,结果为真,其他值和它们进行比较都返回假值

//  4、对象和非对象之间的相等比较,会将对象先转为基木数据类型再进行判断
     ‘1’=={}  --> '1' == "[object object]" 


//  5、如果两个操作值都是对象,则比较它们是不是指向同一个对象,如果两个操作数都指向同一个对象,则相等操作符返回true ,否则返回false

var a={} ;
var b=a;

var c={};
console.log(a==b); // true

console.log(a==c); // false 

 15、js中 isNaN 与 Number.isNaN()  的区别

// js中 isNaN 和 Number.isNaN 的区别?
//  isNaN : 为了到断一个计算结果或者变量的值是否为NaN

//  isNaN(value) : value表示检测的值
//  isNaN 的判断过程 :  首先进行类型检测,如果传入的参数不是数值类型,第二步将传入的参数转为数值类型,然后再进行是否为NaN的判断
 

Number("")    // 0
Number(null)  // 0
Number(true)  // 1
Number(false) // 0
Number(undefined)  // NaN
Numben('aa') // NaN

-----------isNaN()--------------- 

//isNaN()
console.log(isNaN(NaN));      // true
console.log(isNaN(true));     // false 
console.log(isNaN('aaa'));     // true
console.1og(isNaN(null));      // false
console.log(isNaN(''));        // false
consoie.1og(isNaN(undefined)); // true

--------Number.isNaN()---------------'

// Number.isNaN() ES6出来的Number对象的扩展的方法
// Number.isNaN(value): value表示检测的值
// Number.isNaN的判断的过程:首先进行类型检测,如果传入的参数不是数值类型,直接返回felse ,如果判断是数值类型,然后isNaN()的方式进行判断

console.log(Nunber.isNaN(true));     //false
console.log(Number.isNaN(""));       //false
console.log(Number.isNaN(nul1));     //false
console.log(Number.isNaN(NaN));      //true
console.log(Number.isNaN(123));      //false
console.log(Nunber.isNaN( 'aaa'));   //false
console.1og(Number.isNaN(undefined)); //false



16、es6中的 const 定义的 对象的属性 可以修改吗?

// ES6中const定义的对象的属性可以修改吗?

// 可以修动
//  const 是保证 变量指向内存地址 不能改动,变量的值 可以改动

const obj = (name:”张三",age:18);
obj.name= “ 李四 ”   //可以修改
obj={}       
console.log(obj);   // 报错  

 17、ES6中  let、 const 和 var 之问的用法以及区别

 //   ES6中let、 const和var之问的用法以及区别
var:
1、使用var声明的变量既是顶级交量(顶层对象(window对象)的属性)也是全局变量

2、使用var声明的变量存在变量提升的情况
3、使用var可以对一个变量进行多次声明,后面的声明会覆盖前面的变量声明

4、在函数中再次使用var声明这个变量的时候,这个变量就是局部的,如果不是用var,那就全局的

// 使用var声明的变量既是顶级交量(项层对象(window对象)的属性)也是全局变量
 var a=10;
 console.log(window.a); // 10

// 使用var声明的变量存在变量提升(提升变量声明)的情况
 console.log(b); // undefined
 var b = 10;  //声明并且赋值

 // 运行过程
 // var b; 
 // console.log(b); // undefined
 // b=10;

// 使用var可以对一个变量进行多次声明,后面的声明会覆盖前面的变量声明
 var c= 10;
 var c= 40;
 console.log(c); // 40 

//在函数中再次使用var声明这个变量的时候,这个变量就是局部的,如果不是用var,那就全局的
var d=10;
function fun1((){
 var d=20;
}
fun1()
console.log(d); //10

let:
1、 let 所声明交量只在let命令所在的代码块中生效let不存在变量提升
2、 let 不允许在相同的作用域下重复声明
 

//  let所声明变量只在let命令所在的代码块中生效/块级作用域
    let num=18
       console.1og(num);  // 18
     }
//  let不存在交量提升

    let num1;
    console.log(num1);  // 报错

//  let不允许在相同的作用域下重复声明

     num1 = 20   // 报错

const :
const声明一个只读的常量,一旦声明,常量的值就不能改变const一旦声明,就必须赋值
除了以上的其他的都和let一样的

// const声明一个只读的常量。一且声明,常量的值就不能改变

    const sum =103;
    sum = 200;
    console.log(sum);   // 报错,不能再次赋值


//  const一旦声明,就必须赋值

    const total;
    console.log(total);   // 报错,缺少初始值


区别:

交量提升:
var声明的变量存在变量提升,let和lconst不存在变量提升

块级作用域:
var不存在块级作用域,let和const存在块级作用域,只在所在代玛块生效

重复声明:
var允许重复声明,let和const不允许在同一个作用域重复声明

修改声明的变量:
var和let可以改变声明的变量,const,不可以,一旦声明,必须赋值,并且常经的值不能改变
 

18、js中如何的断一个对象是空对象

//  js中如何的断一个对象是空对象
 

//  使用JSON自带的.stringify方法来判断

     var obj={
         name:"张三"
      }
      console.log(JSON.stringify(obj));     // {}  是一个字符串

      if (JSON.stringify(obj) === “0") {
         console.log(“是一个空对象"");
      }

//  使用object.keys()来判断//key:键名
//  value:键值

    var obj1= { name:"张三", age:18 };
    console.log(Object.keys(obj1));    //    返回一个数组

    if ( Object.keys(obj1).length==0 ) {
        console.1og("是一个空对象);
    }

19、 ES6中new一个箭头函效会怎么样     --->报错

 ES6中new一个箭头函效会怎么样     --->报错

// new关键字的执行过程

/*
new构造函效会内存中创建一个空对象this就会指向刚才创建的这个空对象
执行构造函数中代码,给空对象添加属性和方法返回这个新的对象(所以构造函数中不需要return)

*/


/箭头函数
//箭头函数内的this是静态的,指向定义时所在的对象,而不是调用时,this指向不可以改变的var id=10;
  var obj=i
  id:100,
  a:function(){
    // 谁调用这个函数,this就指向谁
    console.log(this.id)  
  },

  b:()=>{
    // this是静态的,指向定义时所在的对象(window对象),所以箭头函数不可以当做构造函数来使用
    console.log(this.id);
  }
)
obj.a()  // 100

obj.b()  //10
console.log(new obj.a());  undefined
console.log(new obj.b());  a{}

 20、js 中对原型的理解

 //JS中对原型的理解

   //  构造函数

    function Person(){


    }
//   prototype(原型)属性,默认对应着一个空对象(没有我们制定的方法和属性),这个空对象就是我们所说的原型对象,每一个prototype都是不相等的

console.log(Person.prototype)   //  

// 显式原型和隐式原型

// 每一个函数都有一个prototype属性,就是显式原型

// 每一个实例对象都有一个_proto_,就是隐式原型
// 实例对象的隐式原型  等于   对应的构造函数的  显示原型的值

   //  构造函数

   function Fun( ){  //内部语句:Fun(this). prototype={}

   }
   console.1log(Fun.prototype);
   var fun=new Fun()、//  内部语句:fun(this)._proto__=Fun. prototype

   console.log(fun._proto_):
   console.log(Fun.prototype===fun._proto__);  // true


//  总结:
//  函数的prototype属性,在定义函数是自动添加的,默认值是一个空对象
//  对象的_proto__属性,创建对象的时自动添加的,默认值是构造函数的prototype属性

21、js中对原型链的理解

//  Js中对原型链的理解:查找对象的属性(方法)


 

function Fun{     // Fun(this).prototype={}
     this.test1=function(){
          console.log( 'test1()");
      }
 }
Fun.prototype.test2=function(){
      console.log( 'test2()');
}
console.log(Fun.prototype);
console.log( object.prototype.__proto__);
var fun=new Fun();    //  fun(this)._proto__=Fun. prototype

fun.test1();     // test1
fun.test2();    //  test2
console.log(fun.tostring())   //  [ object Object ]

fun.test3();    // 报错

22、 js 对原型的修改和重写 

/ JS中对原型的修改和重写
function Person(name){
  this.name=name
}
//修改原型
Person.prototype.getName = function(){
   console.log(this.name);
}
var p=new Person("张三");

// 修改原型不会影响构造函数的显式原型 等于 实例对象的隐式原型

console.log(p._proto_=== Person.prototype);//true
console.log(p.___proto__=== p.constructor.prototype);//true

 
//重写原型  会有影响  p.constructor 的指向改变了

Person. prototype={
  getName:function(){
    console.log(this.name);
  }
}
// 直接给Person的原型对象用对象进行赋值时,p的构造函数指向根构造函数
objectvar p=new Person("张三");  // p(this)._proto__=Person.prototype
console.log(p._proto__===Person.prototype); //true
console.log(p.constructor); // object 指向改变了
console.log(p._proto__===p.constructor.prototype); //false

// 通过constructor 让p的指向恢复

p.constructor=Person;

console.log(p._proto__===p.constructor.prototype); //true

23、for ...of  和 for ... in 的区别

 ES6中 for. . .of  和 for . . .in  (性能差)的区别
// for. . .of遍历获取对象的键值,for. . .in获取对象的键名

// for. . .of只遍历当前对象, for. . .in会遍历对象整个原型链

// 对于数组的遍历

//  for . ..in返回数组中所有可枚举的属性

//  for ..of返回数组的下标对应的属性值

function Person(name,age,sex){
  this.name=name
  this.age=age
  this.sex=sex
}
Person.prototype.height=188

var p=new Person(“张三"",18,男")

P[Symbol.iterator]=function(O){
  var keys = object.keys(this);
  var index = 0;
  return {
    next({
      if(index<keys.length){
         return {value:p[keys[index++]],done:false}
      }else{
         return {value:undefined,done:true}}
    }
  }
}
for(let value of p){
  console.1og(value);   // 张三 18 男

}
------------------------------
for(let key in p){
  console.log(key);     // name age sex height
}

-------------------------

var arr=[1,2,3,4,5]

console.log(arr);

for(let i in arr)
  console.log(i);
}

for(let i of arr){
   console.log(i);
}

 for . ..in,主要是为了遍历对象而产生,不适用于遍历数组 , for ..of,我环可以用来遍历数组,类数组对象,字符串,set  map .....

24、js 中如何判断 一个属性 是属于实例对象 还是继承与构造函数

JS中如何判断一个属性是属于实例对象还是继承于构造函数
通过hasOwnProperty() // 检测一个属性是否属于自身对象,还是继承于原型链上的,

function Person(name,age){
   this.name=name;
   this.age=age;
}
Person.prototype.sex = "男" ;

var p=new Person ("张三",18);

p.phone=12345;
p.height=188;

console.log(p);
console.log(p.hasOwnProperty("phone")); //true

console.log(p.hasOwnProperty ( "sex")); //true

for (let i in p){
  if (p.hasOwnProperty(i)){   //   hasOwnProperty() 筛选掉原型链上的属性
      console.log(p[i]);
  }
}

25、js 中bind 和call 、apply 的作用以及他们的区别

Js中 bind 和call、apply 的作用 以及它们的区别

作用: 改变函数运行时 this 的指向
var uname = " 张三 " 
var obj={
   uname : "李四" ,

   say: function() {
      console.log(this.uname);
   }
 }
obj.say()  //李四
setTimeout(obj.say,0)  // 张三
setTimeout(obj.say.bind(obj),0)  // 李四
//  setTimeout   里面函数里面的this 指向 window  的 this

区别
aplly: 两个参数,第一个是this指向,第二个是函数接收的参数,以数组的形式传入

function fun(...argus){
   console.log(this);

   console.log(...argus);

}
var person={
    myname : "王五"

}
fun.apply(person,[1,2,3,4]);   //  传入的参数必须是一个数组fun(1,2,3,4)


//  如果第一个参数 null 或者 undefined ,this 默认指向 window

fun.apply(nul1,[1,2])
fun.apply(undefined,[1,2])
 

call :  两个参数,第一个是this指向,第二个是参数列表


fun.call(person,1,2,3,4)
//  call和aplly改变this指向原函数立即执行,临时改变this指向一次

fun(1,2,3,4)
//  bind:两个参数,第一个是this指向,第二个是参数列表
//  改变this指向不会立即执行,返回一个永久改变this指向的函数


var bindFun= fun.bind(person)

bindFun(1,2,3,4)
bindFun()
 

总结:三者第一个都是this指向,第二个是函数接收的参数

26、es6 对  promise 的理解以及他的实例方法

ES6中对Promise的理解以及它的实例方法

//  是异步编程的一种解决方案

//  三种状态:pending(进行中),fulfi1led(已成功),rejected(已失败)

//  特点:状态不受外界的影响,只有异步操作的结果,决定当前是哪一种状态

//  一旦状态改变就不会再变(pending-->fufilled , pending-->rejected)
//  用法:Promise是一个构造函数,用来生成Promise实例


//Promise构造函数接收一个函数作为参数,这个函数有两个参数

const p=new Promise(function(resolve,reject) {
    // resolve函数:将Promise对象的状态从未完成变成成功,在异步操作成功的时候调用,          resolve()  //  返回异步操作的结果,作为参数传递出去
    // reject函数:将Promise对象的状态从未完成变成失败,在异步操作失败的时候调用,            reject()  // 返回异步操作的结果,作为参数传递出去
})

//   Promise实例方法
const p = new Promise( function (resolve,reject) {
      setTimeout(O=>{
            const time=new Date().getTime(

             if( time%2 == 0){
                  resolve('成功的数据。 time = '+time)

             }else{
                  reject(·失败的数据,time = '+time)
             }

        },1000)
})
p.then((value)=>{     //  resolved(己成功)的状态
      console.log( 成功的' + value);
},(reason)=>{  //  rejected(已失败)的状态
      console.log( 失败的' + reason);
}).catch((value) => {

      console.log(value)

}).finally(() => {

       console.log('最后的结果')

})

//   then():当实例状态发生改变的时候的回调函数,放回的是一个新的Promise 实例,也就是Promise 可以链式书写的原因。
// catch() :用于指定发生错误的回调函数,一般来说通过 catch 替代 then 中第二个参数

// finally() :用来指定不管Promise对象状态最后如何,都会执行的操作
 

setTimeout(() => {   //  例如多个嵌套  //  多个串联嵌套的异步操作形成的回调地狱
    console.log(111);

    setTimeout(() => {
        console.log(222);

        setTimeout(() => {
           console.log(333);

        },3000)
    },2000)

},1000)
 

----------------------------------------------------

function fun(ms, val,nextval) {
     return new Promise((resolve, reject) => {
           setTimeout(() => {
                resolve(222)
                console.log(111);

           },ms)
      })
}
fun(1000).then((value) => {
       return new Promise((resolve, reject) => {
             setTimeout(() => {
                  console.log(value);

                  resolve(333)
             },2000);

        })
}).then ((value) => {
       return new Promise((resolve, reject) => {
           setTimeout(() => {
                console.1og(value);
           },3000)
      })

})

27、什么是回调地狱(多个串联的异步操作)以及如何使用Promise解决

什么是回调地狱(多个串联的异步操作)以及如何使用Promise解决

 通过 then 链式调用

//歌单--->歌单列表--->歌曲的信息
//需求:一秒钟之后输出1,然后两秒钟之后输出2,然后三秒之后输出3

setTimeout(() =>{
        console.log(1);

        setTimeout(0 =>{
              console.log(2);

              setTimeout(() =>{
                    console.log(3);

              }, 3000)
       }, 2000)

},1000)

------------------使用promise 实现------------------------

function getData() {
      return new Promise((resolve, reject) => {
           setTimeout(() => {
               console.log(1);

               resolve(2)
           },1000)
       })
}
getData() . then ((value)=>{
        return new Promise((resolve, reject) =>{
                setTimeout(() => {
                        console.log(value);

                         resolve(3)
                },2000)
         })

}).then((value)=>{
        return new Promise((resolve,reject) => {
                setTimeout(() =>{
                        console.log(value);

                }, 3000)
        })
})

28、ES6中对Promise.all的理解以及应用场景

ES6中对Promise.all的理解以及应用场景
//  用于将多个Promise实例,包装或一个新的Promise实例

let p1=new Promise((resolve,reject)=>{
        resolve("成功81")
)
let p2=new Promise((resolve,reject)=>i
        resolve("成功e2")
)
let p3=new Promise((resolve,reject)=>{
        resolve("成功83")
)
//  参数可以不是数组,但是必须是iterator接口

let pAll=Promise.al1([p1,p2,p3])

console.log(pAll)

// pAll的状态,由p1,p2,p3来决定,只有当这三个都为成功,pAll才会为成功,
// 但是有一个失败,那么就是失败,这个时候第一个失败的实例的返回值,会传递给pA11的回调函数//如果作为参数的实例,自己定义了catch方法,那么它一旦rejected,不会触pAll的catch方法

pAl1.then((value)=>{
        console.log(value);

}).catch((reason)=>{
        console.log(reason)

})
// 多个请求结果合并在一起

function getBannerList(){
     return new Promise((resolve,reject)=>{
          setTimeout(O=>{
              resolve( 轮播图的数据")

          },108e)
     })
}

function getMusicList(() {
     return new Promise((resolve,reject)=>{
        setTimeout(() => {

             resolve( "歌曲列表的数据')

         } ,2000)
   })
}
function getCateList(){
    return new Promise((resolve,reject)=>i
        setTimeout(() => {
             resolve(歌单分类的数据')

        },3000)

}

function initLoad() {
        let All= Promise.al1([getBannerList(),getMusicList(),getcateList(])

        console.log(All);
        All.then((value) => {
                console.log(value);”
        }
initLoad()

 

 29、ES6中Promise.race的用法以及使用场景

ES6中Promise.race的用法以及使用场景
// 将多个Promise实例包装成一个新的Promise实例

let p1 = new Promise((resolve,reject) =>{
        setTimeout(() =>{
            resolve(p1成功)

        }, 2000)
})
let p2=new Promise((resolve,reject)=>{
     setTimeout(()=>{
         resolve('p2成功‘)

   },1000)
})
//调用
const prace=Promise.race([p1,P2];

console.log(prace);


//Promise.race区别于Promise.all:只要实例中有一个先改变状态,就会把这个实例的多数的返回值传给prace的回调函的/使用场景:请求超时提示


function request(){
        return new Promise((resolve,reject)=>{
                setTimeout(() =>{
                        resolve("请求成功")

                },4000)

        })

}
function timeout() {
      return new Promise((resolve,reject)=>{
           setTimeout(()=>{
                reject(网络不佳,请求超时")

           },3000)
      })

}

Promise.race( [request(),timeout()] ).then((value)=>{
        console.1og(value);
}).catch((reason) => {
console.log(reason);

})

30、 ES6中使用Promise封装ajax

// ES6中使用Promise封装ajax
// http://localhost:3808/personalized21imit-10
 

function getsON(ur1){

  return new Promise((resolve, reject) =>{
    //创建一个实例对象
    let xhr = new XMALHttpRequest();
    //新建一个http请求
    xhr.open( 'GET", url, true);
    //发送http请求
    xhr.send(null)
    //设置状态的监听函数
    xhr.onreadystatechange = function(){
        if(xhr.readyState !== 4) return//表示请求完成
        //当请求成功或者失败,需要改变promise实例的状态
        if (xhr.status >=200 && xhr.status < 300){
            resolve(xhr.responseText)/请求结果
        }else{
            reject(new Error((xhr. statusText))
        }
    }
    //设置错误的监听函资
    xhr.onerror = function (){
        reject(new Error(xhr.statusText))
    }
    //设置响应数据的类型
    // xhr.responseType - 'json"”
  })
}

    getJSON( " http://localhost:3000/personalized?1imit-10').then((value)=> {                              
        console.1og(as0w. parse(value));
    }).catch((reason) =>{
        console.log(reason);
})

31、Js中ajax(Async Javascript and XML)的原理是什么?如何实现

Js中ajax(Async Javascript and XML)的原理是什么?如何实现


原理: 通过XNLHttpRequest对象来向服务器发送异步请求,从服务器获取数据,然后用js来操作DOM去更新页面


实现过程:
-创建Ajax的核心对象 XMLHttpRequest对象

        new XMLHttpRequest(()实例化对象
-通过 XMLHttpRequest对象的 open()方法与服务端建立连接

        new XMLHttpRequest().open(method:表示请求方式,url:服务器的地址)

-构建请求所需的数据内容,并通过XMLHttpRequest 对象的 send()方法发送给服务器端。

         new XMLHttpRequest(.send(body:发送的数据)

        如果使用get 请求发送数据,send()参数设置为null

-通过 XNLHttpRequest对象提供的 onreadystatechange事件监听服务器端的通信状态

         new XNLHttpRequest().onreadystatechange主要监听的属性是实例化对象中readyState(五个状态):

0:open()未调用,

1:   send()未调用,

2:send()已经调用,响应头和响应状态已经返回,

3:响应体正在下载,responseText(接收服务端响应的结果)获取到部分的数据,

4:   整个请求过程已经完毕

只要readystate属性值发生了改变,onreadystatechange被触发

-接受并处理服务端向客户端响应的数据结果
-将处理结果更新到HTML页面中

const xhr =new XMLHttpRequest(){
    xhr.open("GET",'http:/ /localhost: 30e0/ personalized?limit=10')
    xhr.send(nul1)
    xhr.onreadystatechange=function(){
        if(xhr.readystate === 4){
            if(xhr.status>=200 && xhr.status<300){
                console.1og(xhr.responseText);
            }
            let obj=JSON.parse(xhr.responseText)
            console.log(obj);
            obj.result.forEach(item =>{
                var div=document.createElement('div');
                div.innerHTML=item.name
                document.querySelector( 'body' ).appendchild(div)
            })
        }else if(xhr.status>=400){
            console.1og(“错误信息"+xhr.status);
        }
    }
}


http:// localhost: 30ee/personalized?limit=10
 

 32、Js中localstorage和sessionStorage的区别

Js中localStorage和lsessionStorage的区别

localstorage:永久存储在本地,适合保存在本地的数据
sessionStorage:会话级的存储,敏感账号一次性登录

相同点:
都是保存在浏览器端
不会把数据自动的发送给服务器,仅在本地保存
只能存储字符串,可以将对象JSON.stringfy()编码之后进行存储

不同点:
存储大小限制不同:sessionStorage存储的大小为5M, 1ocalstorage存储大小为20M
数据有效期不同:

localStorage: 始终有效,窗口关闭或者浏览器关闭,一直保存,持久保存数据sessionStorage: 仅在当前浏览器窗机关闭前有效,会话级存储
作用域不同:

sessionStorage: 在不同的浏览器窗口否会进行共享,只有同一个页面中

localStorage: 在所有的同源的窗口下可以共享的
 

33

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值