JS学习笔记三(typeof,this,arguments,克隆,数组,类数组)

1. javascript语言typeof 可能返回的结果

boolean string number undefined object function 共六个

this

  1. 函数预编译过程this --> window
  2. 全局作用域里this --> window
  3. call/apply 可以改变函数运行时this指向
  4. obj.func(); func()里面的this指向obj

示例代码:

  <script>
        var name = 222;
        var a = {
            name : "111",
            say : function () {
                console.log(this.name);
            }
        }    
        var fun = a.say;
        fun(); // 222
        a.say(); // 111
        var b = {
            name : "333",
            say : function(fun) {
                fun();
            }
        }

        b.say(a.say); // 222
        b.say = a.say;
        b.say(); // 333
    </script>

arguments

arguments.callee 指向函数自身引用

func.caller

返回调用指定函数的函数.

  <script>
        function test () {
            demo();
        }
        function demo () {
            console.log(demo.caller)
        }
        test()
    </script>

输出结果:

ƒ test () {
            demo();
        }

严格模式下不能使用

"use strict"

面试题:

 <script>
  var foo = 123;
   function print() {
       this.foo = 234;
       console.log(foo); // 234
   }
   print();
</script>
    <script>
        var foo = 123;
        function print() {
            // var this = Object.create(print.prototype)
            this.foo = 234;   
            console.log(foo); // 123
        }
        new print();
    </script>

克隆

浅层克隆

   var obj = {
            name : 'abc',
            age : 123,
            sex : 'female',
        }
        var obj1 = {}
        function clone(origin, target) {
            var target = target || {};
            for(var prop in origin) {
                target[prop] = origin[prop];
            }
            return target
        }

        clone(obj, obj1);

深层克隆

 <script>
        var obj = {
            name : 'abc',
            age : 123,
            card : ['visa','master'],
            wife : {
                name : "bcd",
                son : {
                    name : "aaa"
                }
            }
        }
        var obj1 = {}

        function deepClone(origin, target) {
            var target = target || {},
            toStr = Object.prototype.toString,
            arrStr = "[object Array]";

            for(var prop in origin) {
                if(origin[prop] !== "null" && origin.hasOwnProperty(prop)) {
                    if(typeof(origin[prop]) == 'object') {
                        // if(toStr.call(origin[prop]) == arrStr) {
                        //     target[prop] = [];
                        // }else{
                        //     target[prop] = {};
                        // }
                        target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {}
                        deepClone(origin[prop], target[prop])
                    }else{
                        target[prop] = origin[prop]
                    }
                }
            }

            return target

        }
        
        deepClone(obj, obj1)

    </script>

数组

数组的定义:
  • new Array(length/content);
  • 字面量
    <script>
        var arr1 = [1,2,3,4];
        var arr2 = new Array(1,2,3,4);
        var arr3 = new Array(10);
    </script>

输出结果:
在这里插入图片描述

数组的读和写

js数组几乎没有什么报错

  • arr[num] // 不可以溢出读,结果undefined
  • arr[num] = xxx; // 可以溢出写
数组常用的方法 ES3.0
  1. 改变原数组
    push, pop, shift, unshift, sort, reverse
    splice

push实现:

    <script>
        var arr = [1,2,3];
        Array.prototype.push = function() {
            for(var i = 0; i < arguments.length; i++) {
                this[this.length] = arguments[i];
            }
            return this.length;
        }
    </script>

unshift:在数组前面插入数据
shift: 在数组前面拿出数据

sort: 对数组的元素进行排序


    <script>
        // 1. 必须写两形参
        // 2. 看返回值  1)当返回值为负数时,那么前面的数放在前面
        //             2) 为正数,  那么后面的数放在前面
        //             3) 为0, 不动
        var arr = [1,7,3,4,19];
        arr.sort(function(a,b) {

            // return a-b;  //升序
            return b-a;  // 降序
        })
    </script>

reverse:将数组顺序取反
splice : arr.splice(从第几位开始,截取多少的长度,在切口处添加新的数据) 返回截取的片段

注意:数组一般都是有负数的,原理如下:

  <script>
     var arr = [1,2,3,5];
      console.log(arr.splice(-1,1));  // 5
     // 简写
      splice = function (pos) {
          pos += pos > 0 ? 0 : this.length;   // -1 + 4 =3
      }
  </script>

给一个有序数组,乱序

   <script>
        // 给一个有序数组,乱序
        var arr = [1,2,3,4,5,6,7,8,9,10];
        arr.sort(function() {
            return Math.random() - 0.5;
        })
    </script>
  1. 不改变原数组
    concat, join --> split, toString, slice

    concat 拼接数组
    slice (从该位开始截取,截取到该位)

    <script>
        var arr = [1,2,3,4,5,6];
        var newArr = arr.slice(1,3);
        var newArr1 = arr.slice(1);
        console.log(newArr);  // [2, 3]
        console.log(newArr1); // [2, 3, 4, 5, 6]
    </script>

join 用参数连接数组值

<script>
   var arr = [1,2,3,4,5,6];
   var newArr = arr.join('-');
   var newArr1 = arr.join('呵呵');
   console.log(newArr);  // 1-2-3-4-5-6
   console.log(newArr1); // 1呵呵2呵呵3呵呵4呵呵5呵呵6
</script>

split 把一个字符串分割成字符串数组。

类数组

  1. 可以利用属性名模拟数组的特性
  2. 可以动态的增长length属性
  3. 如果强行让类数组调用push方法,则会根据length属性值的位置进行属性的扩充。

条件:属性要为索引(数字)属性,必须有length属性,最好加上push

<script>
        var obj = {
            "0" : "a",
            "1" : "b",
            "2" : "c",
            name : "abc",
            age : 123,
            length : 3,
            push : Array.prototype.push,
            splice : Array.prototype.splice
        }
    </script>

题目:

  1. 封装type
  <script>
        function type(target) {
            var ret = typeof(target);
            var template = {
                "[object Array]" : "array",
                "[object Object]" : "boject",
                "[object Number]" : "number - object",
                "[object Boolean]" : "boolean - object",
                "[object String]" : "string - object"
            }
            if(target === null ) {
                return 'null';
            }
            if (ret == 'object') {
                var str = Object.prototype.toString.call(target);
                return template[str];
            }else{
                return ret;
            }
        }
    </script>
  1. 数组去重,要求在原型链上编程

方法一:

  <script>
        var arr = [1,1,2,3,2,3,4,3,4,5];
        Array.prototype.unique = function() {
            var temp = {},
                arr = [],
                len = this.length;
            for(var i = 0; i < len; i++) {
                if(!temp[this[i]]) {
                    temp[this[i]] = "abc";
                    arr.push(this[i]);
                }
            }
            return arr;
        }
        console.log(arr.unique()) ; // [1, 2, 3, 4, 5]
    </script>

注意:
一旦经历了var的操作,所得出的属性,window,这种属性叫做不可配置的属性
不可配置的属性delete不掉

面试题:

  1. 一个字符串[a-z]组成,请找出该字符串第一个只出现一次的字母;
 <script>
        var str = "dslgaihggfdlgjirnbldfzgfdghdfgsd"
        // 字符串去重
        var str1 = [].filter.call(str,(s,i,o) => o.indexOf(s) == i);
        console.log(str1); //  ["d", "s", "l", "g", "a", "i", "h", "f", "j", "r", "n", "b", "z"]
        for(var i in str1) {
            var num = 0;
            for(var j=0; j < str.length; j++) {
                if(str1[i] == str[j]) {
                    num ++;
                }
            }
            if(num ==1){
                console.log(str1[i])
                break
            }
        }
    </script>
  1. 字符串去重;
<script>
        var str = "fagrhsafaerefs";
        // es6的函数写法
        var str1 = [].filter.call(str,(s,i,o)=>o.indexOf(s)==i).join('');
        // var str2 = [].filter.call(str,function(s,i,o){return o.indexOf(s)==i;}).join('');
        console.log(str2);
    </script>

核心思想为使用数组的filter方法过滤掉除第一次出现的字符以外其它字符,然后join连接字符串,s、i、o 3个参数分别为:当前字符、当前字符索引、原字符串

此方法妙处在于利用js的call方法改变宿主,使用字符串调用数组中的过滤方法(字符串无此方法),减少了复杂的循环步骤;并且此方法没有使用多余的变量减少内存开支;巧妙的利用indexOf取出字符串中第一次出现的字符(非第一次出现的字符被过滤掉)。因而实现此需求。

发布了69 篇原创文章 · 获赞 96 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_40693643/article/details/102918883