• js基础知识复习2


    第一章 走进 JAVASCRIPT 黑洞

    1.传值和传址

    基本数据类型复制的是值,

    引用数据类型复制的是地址,

    /*
    let a = 1;
    let b = a;
    console.log(a,b) //1,1
    b = 2;
    console.log(a,b) //1,2
    */
    let a = {name:"kangxinzhi"};
    let b = a;
    console.log(a,b) //{name:"kangxinzhi"},{name:"kangxinzhi"}
    b.name = "kxz"
    console.log(a,b)  //{name:"kxz"},{name:"kxz"}

    2.null和undifined详解

    基本数据类型空为undifined

    引用数据类型空为null

    null是个对象

    3.环境污染(局部污染外部)

    /*
    name="kxz"
    function change(){
       name="kang"   
    }
    change();
    console.log(name) //"kang"
    */
    //原因:变量未声明,成为全局变量,造成全局污染。解决方案:使用严格模式提示
    
    "use strict"
    name="kxz"
    function change(){
       name="kang"   
    }
    change();
    console.log(name) //"kxz"

    第二章 JavaScript 运算符与流程控制

    1.比较运算符注意事项

    let a=1;
    let b="1";
    a==b    //true存在隐式转换,这里的b转化为数字类型 数字和数字的比较
    a===b  //false   字符串和数字的比较

    2.break,continue和label标签的使用

    break停止整个循环

    continue停止当前循环走下个循环

    testlabel:for(let i=0;i<10;i++){
      for(let j=0;j<10;j++){       
            if(i+j>10){
               break testlabel; //跳到最外层testlabel循环       
            }
        }
    }

    3.for-in;for-of的使用

    for-in用来遍历数组时返回的下标;遍历对象时返回的是对象的key

    for-of用来遍历数组时返回的是值;遍历对象时返回的是对象的value(用来处理迭代对象)

    let arr = ["apple","banana","orange","melon"];
    let msg = {name:"kang",age:"18",sex:"man"};
    
    for(let index in arr){
       console.log(i); //0,1,2,3
       console.log(arr[i]); //"apple","banana","orange","melon"               
    }
    for(let value of arr){
       console.log(value); //"apple","banana","orange","melon"       数组时迭代对象       
    }
    for(let key in msg){
       console.log(key); //name,age,sex
       console.log(msg[key]); //"kang","18","man"               
    }
    for(let value of msg){
       console.log(value); //报错msg不是迭代对象
    }
    for(let value of "kang"){
      console.log(value) //k a n g 字符串也是可迭代对象
    }

    第三章 JavaScript 值类型使用

    1.typeof 能判断基本类型和function

    A instanceof Array 判断复杂数据类型,它的原理是判断A的protote是否在Array原型链上

    2.模板字面量的使用和字符串转义( /t 制表符  /n换行符) 

    let year="1998年";
    let name="康心志";
    console.log(name+"出生于"+year);//康心志出生于1998年
    console.log(`${name}出生于${year}`)//康心志出生于1998年
    let lessons=[{title:"vue"},{title:"react"},{title:"angular"}];
    console.log(`${lessons.map(e=>{e.title})})  // , ,
    console.log(`${lessons.map(e=>{return e.title})})//vue react angular
    console.log(`${lessons.map(e=>e.title)}`) //vue react angular

    3.标签模板实例操作

    在模板字面量``前加一个函数,函数的第一个参数是模板中的string,第二个可用扩展元素表示剩余的所有参数它表示的是每个${}的内容

    let year="1998年";
    let name="康心志";
    function tag(strings,...vars){
       console.log(strings);
       console.log(vars)      
    }
    console.log(tag`${name}出生于${year}`)
    //["", "出生于", "", raw: Array(3)]
    //["康心志", "1998年"]

    4.字符串的常用方法

    toUpperCase()大写  toLowerCase()小写  trim()去除字符串两端空格  charAt()获取某个下标的字符  

    slice()截取字符串  substring()截取字符串  substr()截取字符串

    indexOf()查找某个字符串的坐标,没有就返回-1,第二个参数表示从第几个字符串开始查找  includes()是否存在某个字符返回布尔值,第二个参数表示从第几个字符开始查找  lastIndexOf()从末尾开始查找

    startsWidth()字符串是否以某个字符开头  endsWidth()字符串是否以某个字符结尾

    replace()字符串替换  repeat()重复输出某个字符串

    split()字符串转为数组  数组.join(,)数组转为字符串

    let a="KangXinZhi";
    a.toUpperCase()//"KANGXINZHI" 
    a.toLowerCase();//"kangxinzhi"
    "    xxx  ".trim()//"xxx"
    a.charAt(5)//i
    a.slice(1);//angXinZhi
    a.substring(1);//angXinZhi
    a.substr(1);//angXinZhi
    a.slice(1,3);//an
    a.substring(1,3);//an
    a.substr(1,3);//ang
    a.slice(-3,-1);//Zh
    a.substring(-3,-1);//KangXinZhi
    a.substr(-3,2);//Zh
    a.replace("Kang","k")//kXinZhi
    "*".repeat(3);//"***"
    a.split("");//["K", "a", "n", "g", "X", "i", "n", "Z", "h", "i"]
    ["k","x","z"].join(,);//"kxz"

     5.类型转换和隐式转换

    字符串,对象的toString()方法,转为字符串

    字符串  使用运算符+-*/转为数字

    字符串或数字 前使用!!转为布尔值

    String()转字符串,Boolean()转布尔值,Number()转数字,Object()转对象

    boolean只有6种情况为false 其他为true

    1、undefined(未定义,找不到值时出现)

    2、null(代表空值)

    3、false(布尔值的false,字符串"false"布尔值为true)

    4、0(数字0,字符串"0"布尔值为true)

    5、NaN(无法计算结果时出现,表示"非数值";但是typeof NaN==="number")注意NaN===NaN为false 它是唯一一个不等于自身的

    6、""(双引号)或''(单引号) (空字符串,中间有空格时也是true

    注意空数组空对象,负值转的布尔值时都为true

    6.Number的一些常用函数

    number.toString()数字转为字符串  Number.isInteger(number)判断数字是否是整数  Number.isNaN(number)判断是否是NaN  Object.is(number,NaN)判断是否是NaN

    parseInt()转为整形  parseFloat()转为浮点数  Number.toFixed(1)保留一位小数

    Math.max()  Math.min()  Math.ceil()取最接近的最大整数  Math.floor()取最接近的最小整数  Math.round()四舍五入  Math.random()随机数

    7.Data的一些常用函数

    时间戳(TIMESTAMP)指从1970-01-01 00:00:00到现在的毫秒数

    new Date() //获取当前时间ISO
    Date.now()  //当前时间戳TIMESTAMP
    const start=Date.now();
    for(let i=0;i<20000000;i++)
    const end =Date.now();
    console.log(end-start) //计算脚本执行时间
    console.time("for")
    for(let i=0;i<20000000;i++)
    console.timeEnd("for") //计算脚本执行时间

    ISO和TIMESTAMP的转换

    ISO转TIMESTAMP
    const date=new Date();
    console.log(date*1);
    console.log(Number(date));
    console.log(date.valueOf());
    console.log(date.getTime());
    TIMESTAMP转ISO
    const TIMESTAMP=date.valueOf();
    console.log(new Date(TIMESTAMP));

    日期格式格式化

    function dateFormat(date,format="YYYY-MM-DD hh:mm:ss"){
        const config = {
            YYYY : date.getFullYear(),
            MM : date.getMonth(),
            DD : date.getDate(),
            hh : date.getHours(),
            mm : date.getMinutes(),
            ss : date.getSeconds()
        }
         for(const key in config){
             format=format.replace(key,config[key]);
        }
         return format;
    }
    console.log(dateFormat(date)) //2020-9-21 10:29:14
    console.log(dateFormat(date,"YYYY年MM月"))//2020年9月

    优秀的日期处理库moment.js

    http://momentjs.cn/

    //npm install moment --save  
    moment().format('MMMM Do YYYY, h:mm:ss a'); // 十月 21日 2020, 10:31:44 上午
    moment().format('dddd');                    // 星期三
    moment().format("MMM Do YY");               // 10月 21日 20
    moment().format('YYYY [escaped] YYYY');     // 2020 escaped 2020
    moment().format();                          // 2020-10-21T10:31:44+08:00

    第四章 JavaScript 数组挖掘

    1.数组创建的小细节

    用new Array()创建数组时,当只填入一个数字,它表示创建的长度是该数字,其每一项的值是undifined

    为了解决这一问题,新版可以用Array.of()来创建,

    let arr=new Array(6);
    arr.length //6
    arr[0]      //undifined
    let arr2=Array.of(6);
    arr2.length  //1
    arr2[0]     //undifined

     2.数组的常用方法

    push()  pop()  unshift()  shift()  fill()填充  copywithin(i,j,k)用于操作当前数组自身,用来把某些个位置的元素复制并覆盖到其他位置上去。

    slice(i,j)截取数组从第i截取到第j项,不改变原数组  splice(i,j,k)截取数组从第i截取j个元素,用k替换掉其内容,改变原数组

    indexOf()查找某项的下标,没有就返回-1,第二个参数表示从第几项开始查找  includes()是否存在某个项返回布尔值,第二个参数表示从第几项开始查找  lastIndexOf()从末尾开始查找

    find(callback)查找数组中第一个符合条件的值  findIndex(callback)查找数组中第一个符合条件的值的索引

    sort((a,b)=>{return a-b})数组排序

    清空数组的几种方式:

    let arr=[1,2,3,4];
    arr=[];
    arr.length=0;
    arr.splice(0,arr.length);
    while(arr.pop()){};
    while(arr.shift()){};
    //手写find
    function myfind(arr,callback){
       for(let value of arr){
           if(callback(value)){return value}
       }   
        return undefined;
    }
    myfind([1,2,3,4,5],e=>{return e==3}) //3
    //手写sort
    function mysort(arr,callback){
       for(let m in arr){
           for(let n in arr){
               if(callback(arr[m],arr[n])<0) {
                   let t=arr[n];
                   arr[n]=arr[m];
                   arr[m]=t;
                }  
            }   
       }  
        return arr;       
    }    

      2.数组的遍历

    1.forEach((item,index,arr)=>{},{}) 遍历数组,第一参数回调函数(每一项,索引值,原数组),第二个参数this指向的对象,不填的话this指向windows

    2.使用迭代器iterator

    let arr=["kang","xin","zhi"];
    let arrkeys=arr.keys();
    arrkeys.next();//{value: 0, done: false}
    arrkeys.next();//{value: 1, done: false}
    arrkeys.next();//{value: 2, done: false}
    arrkeys.next();//{value: undefinew, done: true}
    
    let arrvalues=arr.values();
    arrvalues.next();//{value: "kang", done: false}
    arrvalues.next();//{value: "xin", done: false}
    arrvalues.next();//{value: "zhi", done: false}
    arrvalues.next();//{value: undefined, done: true}
    for(let values of arr.values()){
        console.log(values)//kang xin zhi
    }
    for(let keys of arr.keys()){
        console.log(keys )//0 1 2
    }
    for(let [keys,values] of arr.entries()){
        console.log(values)//kang xin zhi
        console.log(keys )//0 1 2
    }

    3.every()和some()

    every()是对数组中每一项运行给定函数,如果该函数所有一项返回true,则返回true。一旦有一项不满足则返回flase

    some()是对数组中每一项运行给定函数,如果该函数满足任一返回true,则返回true

    var arr = [ 1, 2, 3, 4, 5, 6 ]; 
     
    console.log( arr.every( function( item, index, array ){ 
        console.log( 'item=' + item + ',index='+index+',array='+array ); 
        return item > 3; 
    }));
    //item=1,index=0,array=1,2,3,4,5,6
    //false
    
    
    console.log( arr.some( function( item, index, array ){ 
        console.log( 'item=' + item + ',index='+index+',array='+array ); 
        return item > 3; 
    })); 
    //item=1,index=0,array=1,2,3,4,5,6
    //item=2,index=1,array=1,2,3,4,5,6
    //item=3,index=2,array=1,2,3,4,5,6
    //item=4,index=3,array=1,2,3,4,5,6
    //true 

    4.filter过滤器

    let arr=[100,55,32,65,84]
    arr.filter((item,index,value)=>{return item>60})//[100,65,84]
    //手写 filter
    function myfilter(arr,callback){
       let newarr=[];
       for(let value of arr){
           if(callback(value)==true){
                newarr.push(value)  
           }
       }  
        return newarr;    
    }
    myfilter([100,55,32,65,84],(item,index,value)=>{return item>60})
    //[100, 65, 84]

     5.map映射数组

    对于值类型来说返回一个新的数组

    对于引用类型来说会改变原数组的内容(可以不改变)

    let arr=[1,2,3,4,5]
    let arr2=arr.map((value,index,array)=>{return value+1})
    console.log(arr)//[1,2,3,4,5]
    console.log(arr2)//[2,3,4,5,6]
    
    let arr3=[{name:"kang",age:18},{name:"xin",age:19},{name:"zhi",age:20}]
    arr3.map((value)=>{value.sex="man"})
    console.log(arr3)
    //[{name:"kang",age:18,sex:"man"},{name:"xin",age:19,sex:"man"},{name:"zhi",age:20,sex:"man"}]
    
    //若想不改变引用类型原数据,可以使用以下方法
    let arr4=[{name:"kang",age:18},{name:"xin",age:19},{name:"zhi",age:20}]
    let arr5=arr4.map((value)=>{return Object.assign({sex:"man"},value) })
    let arr6=arr4.map((value)=>{return {name:value.name,age:value.age,sex:"man"}})
    //arr4  [{name:"kang",age:18},{name:"xin",age:19},{name:"zhi",age:20}]
    //arr5  [{name:"kang",age:18,sex:"man"},{name:"xin",age:19,sex:"man"},{name:"zhi",age:20,sex:"man"}] 
    //arr6  [{name:"kang",age:18,sex:"man"},{name:"xin",age:19,sex:"man"},{name:"zhi",age:20,sex:"man"}]

    6.reduce

    /*
    reduce比之前见到的遍历函数的回调函数中多了一个pre参数,它表示函数每次遍历的返回值,若不给定其初始值,它第一次就表示数组中第一项,接下来表示每一项遍历的返回值。
    若给reduce(callback,n)第二个参数n,则表示pre的初始值是n,接下来表示每一项遍历的返回值。
    */
    
    let arr=[1,2,3,4,5];
    arr.reduce(function(pre,value,index,array){
        console.log(pre,value)
    })
    //1             2
    //undefined  3
    //undefined  4
    //undefined  5
    
    arr.reduce(function(pre,value,index,array){
        console.log(pre,value)
        return "kxz"
    },0)
    //0              1
    //kxz           2
    //kxz           3
    //kxz           4
    //kxz           5
    
    //判断数组中的最大值
    function maxnum(array){
       return array.reduce((pre,value)=>{
            return pre>value?pre:value;
      })
    }
    maxnum([99,56,43,41,255]); //255

    第五章 好用的 JavaScript Symbol 类型

    1.symbol的定义

    Symbol用于防止属性名冲突而产生的,比如向第三方对象中添加属性时。

    symbol定义的值永远是唯一的

    let kxz= Symbol();
    let kang = Symbol();
    console.log(kxz); //symbol
    console.log(kxz== kang ); //false
    
    //symbol不可以添加属性
    kxz.name = "康心志";
    console.log(hd.name); //报错

    2.symbol描述参数

    //可传入字符串用于描述Symbol,方便在控制台分辨Symbol
    let kxz= Symbol("is name");
    let kang = Symbol("这是一个姓");
    console.log(kxz); //Symbol(is name)
    console.log(kang.toString()); //Symbol(这是一个姓)
    
    //传入相同参数Symbol也是独立唯一的,因为参数只是描述而已,但使用 Symbol.for则不会
    let kxz2= Symbol("kang");
    let kxz3 = Symbol("kang");
    console.log(kxz2== kxz3); //false
    
    //使用description可以获取传入的描述参数
    let kxz4= Symbol("kang");
    console.log(hd.description); //kang

    3.Symbol.for和Symbol.keyFor 

    //Symbol.for根据描述获取Symbol,如果不存在则新建一个Symbol
    //使用Symbol.for会在系统中将Symbol登记
    //使用Symbol则不会登记
    let hd = Symbol.for("后盾人");
    let edu = Symbol.for("后盾人");
    console.log(hd == edu); //true
    
    
    //Symbol.keyFor 根据使用Symbol.for登记的Symbol返回描述,如果找不到返回undefined 。
    let hd = Symbol.for("后盾人");
    console.log(Symbol.keyFor(hd)); //后盾人
    
    let edu = Symbol("houdunren");
    console.log(Symbol.keyFor(edu)); //undefined

    4.对象属性

    Symbol 是独一无二的所以可以保证对象属性的唯一。

    • Symbol 声明和访问使用 [](变量)形式操作

    • 也不能使用 . 语法因为 .语法是操作字符串属性的。

    //下面写法是错误的,会将symbol 当成字符串symbol处理
    let symbol = Symbol("后盾人");
    let obj = {
      symbol: "hdcms.com"
    };
    console.log(obj);
    
    //正确写法是以[] 变量形式声明和访问
    let symbol = Symbol("后盾人");
    let obj = {
      [symbol]: "houdunren.com"
    };
    console.log(obj[symbol]); //houdunren.com

    5.遍历属性

    //Symbol 不能使用 for/in、for/of 遍历操作
    let symbol = Symbol("后盾人");
    let obj = {
      name: "hdcms.com",
      [symbol]: "houdunren.com"
    };
    
    for (const key in obj) {
      console.log(key); //name
    }
    
    for (const key of Object.keys(obj)) {
      console.log(key); //name
    }
    
    
    //可以使用 Object.getOwnPropertySymbols 获取所有Symbol属性
    for (const key of Object.getOwnPropertySymbols(obj)) {
      console.log(key);
    }
    
    //也可以使用 Reflect.ownKeys(obj) 获取所有属性包括
    Symbolfor (const key of Reflect.ownKeys(obj)) {
      console.log(key);
    }
    
    //如果对象属性不想被遍历,可以使用Symbol保护
    const site = Symbol("网站名称");
    class User {
      constructor(name) {
        this[site] = "后盾人";
        this.name = name;
      }
      getName() {
        return `${this[site]}-${this.name}`;
      }
    }
    const hd = new User("向军大叔");
    console.log(hd.getName());
    for (const key in hd) {
      console.log(key);
    }

     6.对象

    1.查看对象的属性

    对象自己的属性:obj.hasOwnProperty(属性)

    对象自己和原型上的属性:属性  in   obj

    设置自己的属性:Object.setPrototypeOf(属性)

     对象的合并:Object.assgin({a:1},{b:2}) //{a:1,b:2}

    2.浅拷贝,深拷贝

    浅拷贝:使用for/in  Object.assgin  展开语法

    深拷贝:

            let kxz = { name: "kxz", user: { age: 18 } }
            function deepcopy(obj) {
                let newobj = obj instanceof Array ? [] : {};
                for(let [k,v] of Object.entries(obj)){
                    newobj[k]=v instanceof Object ? deepcopy(v):v;
                }
                return newobj;
            }
            let kxz2=deepcopy(kxz);
            kxz2.user.age=19;
            console.log(kxz);
            console.log(kxz2);

     3.构造函数

    定义:通过  new 函数名    来实例化对象的函数叫构造函数。任何的函数都可以作为构造函数存在。之所以有构造函数与普通函数之分,主要从功能上进行区别的,构造函数的主要 功能为 初始化对象,特点是和new 一起使用。new就是在创建对象,从无到有,构造函数就是在为初始化的对象添加属性和方法。构造函数定义时首字母大写(规范)。

    对new理解:new 申请内存, 创建对象,当调用new时,后台会隐式执行new Object()创建对象。所以,通过new创建的字符串、数字是引用类型,而是非值类型。

    4.面向对象抽象设置

    Object.getOwnPropertyDescriptors(对象名); //显示对象的所有权限(value值,writeable是否可写,enumerable是否可遍历,configurable是否可删除)

    Object.defineProperty(对象名,属性名,{value:'新值',writeable:false,enumerable:false,configurable:false}) //修改或添加属性及其权限

    Object.isExtensible(对象名)// 判断是否能向对象中添加属性

    Object.preventExtensions(对象名)//禁止向对象添加属性

    Object.seal()//方法封闭一个对象,阻止添加新属性并将所有现有属性标记为 configurable: false

    Object.isSealed 如果对象是密封的则返回 true,属性都具有 configurable: false

    Object.freeze () //冻结对象后不允许添加、删除、修改属性,writable、configurable都标记为false

    Object.isFrozen()方法判断一个对象是否被冻结

     5.属性访问器

    getter方法用于获得属性值,setter方法用于设置属性,这是JS提供的存取器特性即使用函数来管理属性。

    • 用于避免错误的赋值
    • 需要动态监测值的改变
    • 属性只能在访问器和普通属性任选其一,不能共同存在

    getter/setter

    向对是地用户的年龄数据使用访问器监控控制

    "use strict";
    const user = {
      data: { name: '后盾人', age: null },
      set age(value) {
        if (typeof value != "number" || value > 100 || value < 10) {
          throw new Error("年龄格式错误");
        }
        this.data.age = value;
      },
      get age() {
        return `年龄是: ${this.data.age}`;
      }
    };
    user.age = 99;
    console.log(user.age);

    代理拦截proxy 

    代理(拦截器)是对象的访问控制,setter/getter 是对单个对象属性的控制,而代理是对整个对象的控制

    • 读写属性时代码更简洁
    • 对象的多个属性控制统一交给代理完成
    • 严格模式下 set 必须返回布尔值

    使用方法:

    "use strict";
    const hd = { name: "后盾人" };
    const proxy = new Proxy(hd, {
      get(obj, property) {
        return obj[property];
      },
      set(obj, property, value) {
        obj[property] = value;
        return true;
      }
    });
    proxy.age = 10;
    console.log(hd);

    通过proxy实现双向数据绑定:

    <body>
    <input type="text" v-model="title" />
    <input type="text" v-model="title" />
    <div v-bind="title"></div>
    </body>
    <script>
    function View() {
        //设置代理拦截
      let proxy = new Proxy(
        {},
        {
          get(obj, property) {},
          set(obj, property, value) {
            obj[property] = value;
            document
              .querySelectorAll(
                `[v-model="${property}"],[v-bind="${property}"]`
              )
              .forEach(el => {
                el.innerHTML = value;
                el.value = value;
              });
          }
        }
      );
      //初始化绑定元素事件
      this.run = function() {
        const els = document.querySelectorAll("[v-model]");
        els.forEach(item => {
          item.addEventListener("keyup", function() {
            proxy[this.getAttribute("v-model")] = this.value;
          });
        });
      };
    }
    let view = new View().run();
  • 相关阅读:
    Python
    保护模式(九):挂物理页
    保护模式(八):MmIsAddressValid逆向(PAE)
    保护模式(七):2-9-9-12分页
    保护模式(六):10-10-12分页(二)
    保护模式(五):10-10-12分页(一)
    保护模式(四):任务段与任务门
    保护模式(三):中断门与陷阱门
    保护模式(二):调用门
    保护模式(一):段描述符与段选择子
  • 原文地址:https://www.cnblogs.com/kangxinzhi/p/13842397.html
Copyright © 2020-2023  润新知