JS高级 04

作者: _MARPTS | 来源:发表于2018-05-25 11:29 被阅读0次

    基本包装类型

    • String Number Boolean区别(string number boolean)
    • 1.创建字符串对象
    var str1 = new String('demo');
    console.log(typeof str1)// object
    
    var str2 = String('deme');
    console.log(typeof str2)//string
    
    var str3 = 'demo';
    console.log(typeof str3)//string
    
    • 2.创建数值对象
    var num1 = new Number(10)//object
    var num2 = Number(20)//number
    var num3 = 10 // number
    
    
    • 3.创建布尔对象
    var bool1 = new Boolean(true)//object
    var bool2 = Boolean(true);//boolean
    var bool3 = true// boolean
    
    
    • 4.特殊的创建方式
    var str4 = new Object('demo');
    var num4 = new Object(10);
    var bool4 = new Object(true);
    
    • 5.使用的注意点
      • 引用类型和值类型对比的时候,引用类型会默认调用tostring转换为 再进行判断对比
      var str1 = new String('dd');//0x123
      var str2 = new String('dd');//0x456
      var str3 = 'demo';
      
      console.log(str1 == str2);//fasle
      console.log(str1 === str2);//false
      
      // 引用类型和值类型对比的时候,引用类型会默认引用tostring 再进行判断对比
      console.log(str1 == str3);//true
      console.log(str1=== str3);//false
      
      • 基本数据类型为什么可以访问属性?
        • 1.字符串, 数值, 布尔 在访问属性或调用方法的时候
        • 2.默认会创建一个新的对象与之相对应
        • 3.利用该对象访问属性或者调用方法,得到结果后返回
        • 4.销毁该对象
      var str4 = 'demo111';
      str4.des = 'des';
      console.log(str4.length);
      console.log(str4.des);//undefined
      
      var str5 = new String('demo111');
      str5.des = 'des';
      console.log(str5.des)//des
      
      • 面试题
      Number.prototype.sum = function(){
          console.log(this+20)
      }
      
      var num1 = new Number(10);
      num1.sum();//30
      
      var num2 = 10;
      num2.sum();//30
      
      (10).sum();//30
      
      
      • 注意点
        • 给基本包装类型的原型对象动态添加属性和方法,那么所有基本数据类型可以即时获取,原理同上,但当行代码过后,就会被销毁

    Object.prototype 的属性和方法

    • 1.constructor 指向对应的构造函数
    • 2.hasOwnProperty 判断对象中是否存在指定的实例属性
    • 3.isPrototypeof 判断一个对象是否是指定的对象的原型对象
      • 判断包含是原型链上的原型对象
      function Person(){
          
      }
      
      var obj{
          des:'des'
      }
      
      Person.prototype = obj;
      
      var p1 = new Person();
      
      console.log(obj.isPrototypeOf(p1));//true
      console.log(Object.prototype.isPrototypeOf(p1));//true
      
      
    • 4.propertyIsEnumerable 判断一个属性是否可枚举,如果属性石可枚举的,就可以通过for..in遍历
      var obj = {
          name:'zs',
          age:20
      }
      
      // 获取一个属性的描述信息
      console.log(Object.getOwnPropertyDescript(obj,'name'));
      // 设置name 为不可枚举
      Object.defineProperty(obj,'name',{
      enumerable : false
      })
      
      for(var k in obj){
          console.log(obj[k])
      }
      添加判断是否可枚举代码
      console.log(obj.propertyIsEnumerable('name')); // false
      
    • 5.toString 返回对应的字符创描述信息
      • 1.object 对象- > '[object object]'
      • 2.数组|函数 -> 对应的字符创形式
      • 3.Number 在使用的时候可以传参,表示进制转换
      var obj = {name: 'zs'}
      var arr1 = [1,2,3];
      function fun() {
          
      }
      
      console.log(obj.toString());//'[object,object]'
      console.log(arr1.toString());//'1,2,3'
      console.log(fun.toString());//fun(){}  字符串
      
      
        var num = new Number(20);
      console.log(num.toString(8)); // 24    4*1 + 2*8 = 4 + 16 = 20
      console.log(num.toString(3));// 202    2*1 + 0*3 + 2*3*3 = 2 + 18 = 20
      console.log(num.toString(6));// 32    2*1 + 3 * 6 = 2 + 18 = 20
      
    • 6.toLocateString 大部分情况等价于toString, 特殊情况下会做本地化处理
    • 7.valueOf 返回对应的值
      • 1.object对象返回本身
      • 2.基本包装类型返回对应的基本数据类型的值
      • 3.如期对象返回时间戳
      var obj = {
          name : 'zs'
      }
      console.log( obj.valueOf());//obj对象本身
      
      var str1 = new String('demo');
      var num1 = new Number(10);
      var bool1 = new Boolean(true);
      console.log(typeof str1.valueOf()); // demo
      console.log(typeof num1.valueOf()); // 10
      console.log(typeof bool1.valueOf()); // true
      
      var date = new Date();
      console.log(date.valueOf()); // 1526179038533 时间戳 (ms)
      // 计算机元年到现在 1970 1 1
      
    静态成员和实例成员
    • 实例成员: 直接添加在实例上的属性和方法
    • 原型成员: 直接添加到原型上的属性和方法
    • 静态成员: 直接添加到构造函数上的属性和方法(构造函数本质也是一个对象,也可以拥有自己的属性和方法)
    function Person(){
        this.name = '默认';
        var age = 10; //不是实例成员
    }
    Person.prototype.des ='des';
    
    var p1 = new Person();
    
    // 静态成员
    Person.des = '描述函数';
    Person.log = function () {
        console.log('log');
    }
    
    Object的静态成员(属性和方法)
    • 1.Object.apply 借用其他对象的方法

    • 2.Object.assign 拷贝属性

    • 3.Object.arguments 函数内部的隐藏参数,用来接收实参,保存实参

      function fun(){
        // arguments 不是数组,是一个类似于数组点的结构
          console.log(arguments[1]);
          console.log(Array.isArray(arguments)//false
      }
      fun(1,2,3,4,5,6,7)
      
    • 4.Object.call 借用其他对象的方法

    • 5.Object.create 创建一个新的对象,并设置原型对象

    • 6.Object.caller 返回一个函数,返回调用当前函数的函数

      • 在全局中调用,返回null
      function test1(){
          console.log(test1.caller);//返回调用test1的函数
      }
      
      function test2(){
          test1()
      }
      test2()
      
      console.log(test1.caller)//null
      
    • 7.Object.constructor 指向对应的构造函数

    • 8.Object.getOwnPropertyDescriptor 获取对象中某个实例属性的描述信息

      • Object..getOwnPropertyDescriptor(要获取的对象,要获取的属性)
      • configurable: 是否可配置(1.是否可删除2.是否可以修改该配置包含value,writable,configurable)
      • enumerable 是否可枚举
      • value 值
      • writable 是否可修改
       var obj = {
          name : 'zs',
          age : 20
      }
      
      Object.defineProperty(obj,'name',{
          configurable : true,
          enumerable : false,
          writable : false,
          value : 'zs'
      })
      //writable 可修改
      obj.name = 'ls';
      console.log(obj);
      // configurale 可配置
      console.log(delete obj.name);
      console.log(obj);
      // enumerable 可枚举
      for(var key in obj){
        console.log(key);
      }
      
    • 9.Object.defineProperty 定义一个属性,并设置这个属性的描述信息

      • Object.defineProperty(要操作的对象,要操作的属性,描述对象)
      • 1.如果修改已经存在的属性默认是true
      • 2.如果添加新的属性,默认是false
      var obj = {
          name : 'zs'
      }
      console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
      
      Object.defineProperty(obj,'age',{
      })
      
      console.log(Object.getOwnPropertyDescriptor(obj, 'age'));
      
    • 10.Object.getOwnPropertyNames 获取实例属性的属性名 返回数组,数组存放所有的属性名

    • 11.Object.keys 获取实例属性名(可枚举属性,不包括不可枚举) 返回数组,数组存放所有的属性名

    • 12.Object.getPrototypeof 获取一个对象的原型对象

    • ==13*.Object.preventExtensions 禁止扩展(不能添加,可以删除和修改)==

      • Object.isExtensible 判断一个对象是否是可扩展的
    • ==14*.Object.seal 密封对象 (不能添加,不能删除,可以修改)==

      • 密封对象让对应的对象不能添加新的属性,同时旧有的属性不能删除,但是可以修改已有属性的可枚举性,可配置型,可写性,可修改已有属性的值
      • Object.isSealed 判断一个对象是否是密封的
    • ==15*.Object.freeze 冻结对象
      不能添加属性,不能删除,不能修改==

    这个方法比 Object.seal 更绝,冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的.

    -  Object.isFrozen 判断一个对象是否是冻结的
    

    Function构造函数的使用

    • Function 的参数一定是字符串
    • 不传参,创建出来的是空函数
    • 传1个参数,这个参数作为函数体
    • 传多个参数, 前面的是形参列表,最后一个是函数体
    var fun = new Function('a','b','console.log(a+b);')
    fun3(1,2);
    
    • 注意点
      • 1.函数.name 获取函数名,可以获取,函数名不能修改
    处理函数参数过长的问题(Function构造函数使用)
    • 1.使用+ 拼接
    • 2.使用``包括 反括号
    • 3.使用JS模板
    函数的隐藏参数
    • arguments: 函数内部的隐藏参数,用来接收是从哪并保存实参( 保存的不是一个数组.与数组结构类似)

    • 函数调动: 默认会把实参赋值给形参,并把实参保存在arguments中

    • 实参> 形参 会一次赋值,超出的实参可以通过arguments获取到

    • 实参< 形参, 会依次赋值,没有赋值为undefined

    • arguments.length : 实参的长度

    • 函数名.length : 形参的长度

    function  fun () {
        console.log(arguments[0]);
           
    }
    
    callee 和caller
    • 1.callee 函数内部arguments有一个callee,返回函数自身,常用于匿名函数的递归调用

    • 2.caller 返回调用当前函数的函数

      • 在全局作用域调用返回null;
    • 递归调用

      • 自己调用自己
      • 要有退出条件
    // 使用arguments.callee匿名函数的递归调用
    求1到n的和
    (function (n){
        if(n ==1 ){
            return 1;
        }
        return arguments.callee(n-1)+n
    }
    )(10);
    
    Function小应用(数组去重和求最大值)
    • 用arguments来获取数组的数据,来进行遍历
    • indexOf: 返回元素对应的索引,如果该元素不存在,返回-1
    • 求数组去重
      var fun = new Function(`  var arr = [];
          for (var i = 0; i < arguments.length; i++) {
              if(arr.indexOf(arguments[i]) == -1){
                  arr.push(arguments[i]);
              }
          }
          return arr;`)
      
      

    console.log(fun(9, 12, 3, 4, 5, 3, 5, 2, 3));
    ```

    • 求最大值
       function fun() {
          var maxNum = arguments[0];
          for (var i = 1; i < arguments.length; i++) {
              if(maxNum < arguments[i]){
                  maxNum = arguments[i];
              }
      
          }
          return maxNum;
      }
      console.log(fun(1, 2, 3, 4, 89, 67, 98, 2, 3));
      
    ==Function.prototype原型链==
    • 两个点: Object.prototype 作为对象的时,他的原型对象被修改了,指向null
    • Function.prototype 作为对象的时,他的原型对象被修改了,它指向Object.prototype
    Object和Function 的关系
    • 1.Object和Function 互为对方的实例
    • 2.JS中的对象都是基于Object
    • 3.instanceof 的原理
      • 判断构造函数的原型对象是不是在实例对象的原型链上
    私有变量和私有函数
    • 定义在构造函数内部的变量和函数,在外界无法直接访问
    • 特权方法: 可以访问私有变量和私有函数的实例方法
    function Person() {
        this.name = 'zs';
        var age = 20;
        var logAge = function(){
            console.log(age);
        }
        //特权方法:可以访问私有变量和私有函数的实例方法
        this.test = function(){
            return age;
        }
        
        this.test2 = function(){
             logAge() ;
        }
        
        var p1 = new Person();
        console.log(p1.text());
        p1.text2();
    }
    
    eval函数
    • 可以把字符串转为对应的JS代码

    • 并且马上执行

    • eval 和Function 的区别

      • 1.都可以把字符串转为对应的JS代码
      • 2.eval 把字符串转为代码后会马上执行;Function要调用
    • eval处理JSON数据

      • JSON数据: 一种轻量级的数据结构,可以用来表示数据,保存数据,传输数据,本质是一个字符串
      • JSON操作:
        • 1.把JSON字符串转为对应的对象(JSON.parse)(eval) (反序列化处理)
        • 2.把对象转为JSON数据(JSON.stringify)(序列化处理)
    • 建议:不建议使用(JS是词法作用域,eval可以动态调整词法作用域,性能不好)

    with简单说明
    • 可以把对象的作用域引申到大括号中
    • 作用是为了减少代码量
        var obj = {
            name:'zs',
            age:20,
            des:'des'
        }
        with(obj){
            name= 'ls';
            age = 21;
            des = '22';
            obj.log = 'log';
        }
    
    • 使用注意点:

      • 1.不能使用无前缀的方式添加属性
      • 2.this指向window
      • 3.严格模式禁止使用
    • 以往场合:当需要深层次的引用

    • 使用建议: 不建议使用,用即时函数体可以替代

    ==函数内部this的指向==
    • 函数内部this的指向取决于函数的调用方式
      • 1.函数作为对象方法调用时,this指向当前的对象
      • 2.作为普通函数直接调用,this指向window
      • 3.使用new构造函数调用时,this指向构造函数内部新创建的对象
      • 4.利用call和apply来借用方法时(函数上下文调用),this指向实际调用方法的对象
        var obj = {
            name: 'zs',
            showName:function (){
                console.log(this);
            }
        }
        
        obj.showName();// this -->obj
        
        var fun = obj.showName;
        fun(); // this -> window
        
        function Person() {
            console.log(this);//p1    
        }
        
        var p1 = new Person;
    
    • this的丢失问题
    • 原因: 函数的调用方式发生改变
        var obj = {
            age :20,
            show: function(){
                console.log(this.age)
            }
        }
        
        obj.show();
        
        var fun = obj.show;
        fun(); // this丢失问题undefined
    
    • 用document调用getElementById 这个方法时,内部的this指向document,直接调用,this指向window

    • 调用document.getElementById这个方法时,函数内部的this始终绑定document

     调用document.getElementById这个方法时,函数内部的this始终绑定document
    var getEEle = (function(func){
        return function(){
            return func.apply(document,arguments);
        }
    }
    )(document.getElementById)
    
    var div = getEle('demo');
    console.log(div);
    

    相关文章

      网友评论

        本文标题:JS高级 04

        本文链接:https://www.haomeiwen.com/subject/sxmyjftx.html