JS基础知识

JS基础知识

1-变量类型和计算

1-1 题目

  • JS中使用typeof能得到哪些类型
  • 何时使用=== ,何时使用 ==
  • JS中有哪些内置函数
  • JS变量按照存储方式区分为哪些类型,并描述其特点
  • 如何理解JSON

1-2 知识点

  • 变量类型
  • 变量计算 - 强制类型转换
1-2-1 变量类型
  • 值类型 vs 引用类型
    • 值类型
      特点:不会随赋值而改变
    	// 值类型
    	let a = 100;
        let b = a;
        a = 200;
        console.log('a = ' + a);  // a = 200
        console.log('b = ' + b);  // b = 100
    
    • 引用类型:对象、数组、函数
      特点:会随着赋值而改变,赋值时拷贝的是指向具体内容的指针;可以无限扩展属性
    	// 引用类型:对象
        let a = {age: 20};
        let b = a;
        console.log(a);  // {age: 20}
        console.log(b);  // {age: 20}
        b.age = 21;
        console.log(a);  // {age: 21}
        console.log(b);  // {age: 21}
        // 引用类型:数组
        let arr = [1, 2, 3];
        arr.age = 21;
        console.log(arr);  // [1, 2, 3, age: 21]
        let arr2 = arr;
        console.log(arr2);  // [1, 2, 3, age: 21]
        arr2.age = 22;
        console.log(arr);  // [1, 2, 3, age: 22]
        // 引用类型:函数
        function fun(){}
        fun.age = 21;
        let fun2 = fun;
        console.log(fun.age);  // 21
        console.log(fun2.age);  // 21
        fun2.age = 22;
        console.log(fun.age);  // 22
        console.log(fun2.age);  // 22
    
  • typeof 运算符详解
    • 1、typeof只能区分值类型的详细类型–number,string,boolean,undefined
    • 2、typeof不能区分引用类型的详细类型–typeof可以区分function,但是会把数组、对象和null均视为object
1-2-2 变量计算 - 强制类型转换
  • 字符串拼接
  • ==运算符
  • if语句
    在if语句中会被转换成false的情况,共有6种,分别是:0, NaN, ‘’/“”, null, undefined, false
  • 逻辑运算
    	    // 2-2-2 变量计算 - 强制类型转换
            // 字符串拼接
            let a = 100 + 10;
            let b = 100 + '10';
            console.log(a);  // 110
            console.log(b);  // 10010
            // ==运算符
            console.log(100 == '100');  // true
            console.log(0 == '');  // true
            console.log(null == undefined);  // true
            console.log(100 === '100');  // false
            console.log(0 === '');  // false
            console.log(null === undefined);  // false
            // if语句
            a = true;
            if(a) {
                console.log(a);  // true
            }
            b = 100;
            if(b) {
                console.log(b);  // 100
            }
            let c = '';
            if(c) {
                console.log(c);  // 不执行
            }
            // 逻辑运算
            console.log(10 && 0);  // 0
            console.log('' || 'abc');  // 'abc'
            console.log(!window.abc);  //true
            // 判断一个变量会被当做 true 还是 false
            a = 100;
            console.log(!!a);  // true
            b = '';
            console.log(!!b);  // false
    

1-3 题目解答

  • JS中使用typeof能得到哪些类型
    	// 问题:JS中使用typeof能得到哪些类型
        console.log(typeof undefined);  // undefined
        console.log(typeof 'undefined');  // string
        console.log(typeof 123);  // number
        console.log(typeof true);  // boolean
        console.log(typeof {});  // object
        console.log(typeof []);  // object
        console.log(typeof null);  // object
        console.log(typeof console.log);  // function
    
  • 何时使用=== ,何时使用 ==
    	// 问题:何时使用===  ,何时使用 ==
        if(obj.a == null) {
            // 这里相当于 obj.a === null || obj.a === undefined, 简写形式
            // 这是jQuery源码中推荐的写法,除此之外,都应该使用===
        }
    
  • JS中有哪些内置函数 – 数据封装对象 – 9个
    • Boolean
    • Number
    • String
    • Date
    • Array
    • Function
    • Object
    • RegExp
    • Error
      注意:
      JS中有12个内置对象,除了上面的9个内置函数之外,还有Math, Global(在浏览器中的表现为window), JSON
  • JS变量按照存储方式区分为哪些类型,并描述其特点
    • 值类型
      特点:不会随赋值而改变
    • 引用类型:对象、数组、函数
      特点:会随着赋值而改变,赋值时拷贝的是指向具体内容的指针;可以无限扩展属性
  • 如何理解JSON
    JSON 只不过是一个JS对象而已,同时也是一种文件格式。
    	// 问题:如何理解JSON
        let str1 = JSON.stringify({a: 10, b: 20});  //  json -->  string
        let str2 = JSON.parse('{"a": 10, "b": 20}');  //  string -->  json
        console.log(str1);  //  {"a": 10, "b": 20}
        console.log(str2);  // {a: 10, b: 20}
    

2-原型和原型链

2-1 题目

  • 如何准确判断一个变量是数组类型
  • 写一个原型链继承的例子
  • 描述new一个对象的过程
  • zepto(或其他框架)源码中如何使用原型链

2-2 知识点

  • 构造函数
    	//构造函数
        function Foo(name, age) {
            this.name = name;
            this.age = age;
            this.class = 'class-1';
            // return this;  // 默认有这一行
        }
        let f = new Foo('zhangsan', 20);
        let f2 = new Foo('lisi', 22);  //创建多个对象
        console.log(f);  // Foo {name: 'zhangsan', age: 20, class: 'class-1'}
        console.log(f2);  // Foo {name: 'lisi', age: 22, class: 'class-1'}
    
  • 构造函数 - 扩展
    • var a = {} 其实是 var a = new Object() 的语法糖
    • var a = [] 其实是 var a = new Array() 的语法糖
    • function Foo(){…} 其实是 function Foo = new Function(){…} 的语法糖
    • 使用 instanceof 判断一个函数是否是一个变量的构造函数
  • 原型规则和示例 – 5条
    • 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了"null"之外)
    • 所有的引用类型(数组、对象、函数),都有一个__proto__属性(隐式原型),属性值是一个普通的对象
    • 所有的函数,都有一个prototype属性(显式原型),属性值是一个普通的对象
    • 所有的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的"prototype"属性值
    	// 原型规则和示例1-4
        let obj = {};
        obj.a = 100;
        let arr = [];
        arr.a = 100;
        function fn() {}
        fn.a = 100;
    
        console.log(obj.__proto__);  // Object
        console.log(arr.__proto__);  // Array
        console.log(fn.__proto__);  // f () {[native code]}
    
        console.log(fn.prototype);  // Object
    
        console.log(obj.__proto__ === Object.prototype);  // true
    
    • 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。
    	// 原型规则和示例5
        // 构造函数
        function Foo(name, age) {
            this.name = name;
        }
        Foo.prototype.alertName = function() {
            alert(this.name);
        }
        // 创建实例
        let f = new Foo('zhangsan');
        f.printName = function() {
            console.log(this.name);
        }
        // 测试
        f.printName();  // zhangsan
        f.alertName();
    
    注意:
    • 原型规则和示例5中所有的this均指向f
    • 循环对象自身的属性
    	// 循环对象自身的属性
        for(let item in f) {
            // 高级浏览器已经在of in 中屏蔽了来自原型的属性
            // 但是这里建议大家还是加上这个判断,保证程序的健壮性
            if(f.hasOwnProperty(item)) {
                console.log(item);  // name printName
            }
        }
    
  • 原型链
    	// 原型链
        // 构造函数
        function Foo(name, age) {
            this.name = name;
        }
        Foo.prototype.alertName = function() {
            alert(this.name);
        }
        // 创建实例
        let f = new Foo('zhangsan');
        f.printName = function() {
            console.log(this.name);
        }
        // 测试
        f.printName();  // zhangsan
        f.alertName();
        f.toString();  // 要去 f.__proto__.__proto__中查找
    

在这里插入图片描述

  • instanceof
    • 用于判断引用类型属于哪个构造函数的方法
      f instanceof Foo / Object 的判断逻辑是:
      f的__proto__一层一层往上,能否对应到Foo.prototype / Object.prototype

2-3 题目解答

  • 如何准确判断一个变量是数组类型

    	// 问题:如何准确判断一个变量是数组类型
        let arr = [];
        console.log(arr instanceof Array);  // true
        console.log(typeof arr);  // object
    
  • 写一个原型链继承的例子

    	// 问题:写一个原型链继承的例子
        // 动物
        function Animal() {
            this.eat = function() {
                console.log('animal eat');
            }
        }
        // 狗
        function Dog() {
            this.bark = function() {
                console.log('dog bark');
            }
        }
        Dog.prototype = new Animal();
        // 哈士奇
        let hashiqi = new Dog();
        hashiqi.bark();  // dog bark
        hashiqi.eat();  // animal eat
    

    ==推荐下面这个更加贴近实战的原型继承示例

    	<!DOCTYPE html>
    	<html lang="en">
    		<head>
    		    <meta charset="UTF-8">
    		    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    		    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    		    <title>2-3-原型链继承demo</title>
    		</head>
    		<body>
    		    <div id="div1">Hello World</div>
    		    <script>
    		        // 写一个封装DOM查询的例子
    		        function Elem(id) {
    		            this.elem = document.getElementById(id);
    		        }
    		
    		        Elem.prototype.html = function(val) {
    		            let elem = this.elem;
    		            if(val) {
    		                elem.innerHTML = val;
    		                return this;  // 链式操作
    		            }
    		            else {
    		                return elem.innerHTML;
    		            }
    		        }
    		
    		        Elem.prototype.on = function(type, fn) {
    		            let elem = this.elem;
    		            elem.addEventListener(type, fn);
    		            return this;
    		        }
    		
    		        let div1 = new Elem('div1');
    		        // console.log(div1.html());
    		        div1.html('<p>Hello Imooc</p>')
    		        .on('click', function() {
    		            alert('clicked');
    		        })
    		        .html('<p>javascript</p>');
    		    </script>
    		</body>
    	</html>
    
  • 描述new一个对象的过程

    • 创建一个新对象
    • this指向这个新对象
    • 执行代码,即对this赋值
    • 返回this
    	//构造函数
        function Foo(name, age) {
            this.name = name;
            this.age = age;
            this.class = 'class-1';
            // return this;  // 默认有这一行
        }
        let f = new Foo('zhangsan', 20);
        let f2 = new Foo('lisi', 22);  //创建多个对象
        console.log(f);  // Foo {name: 'zhangsan', age: 20, class: 'class-1'}
        console.log(f2);  // Foo {name: 'lisi', age: 22, class: 'class-1'}
    
  • zepto(或其他框架)源码中如何使用原型链

    • 阅读源码是高效提高技能的方式
    • 但不能“埋头苦钻”,有技巧在其中(阅读之前,可以先看一看别人分析这个源码的文章或视频)
    • 慕课网搜索"zepto设计和源码分析"

3-作用域和闭包

3-1 题目

  • 说一下对变量提升的理解
  • 说明this几种不同的使用场景
  • 创建10个<a>标签,点击的时候弹出来对应的序号
  • 如何理解作用域
  • 实际开发中闭包的作用

3-2 知识点

  • 执行上下文

    • 范围:一段<script>或者一个函数
    • 全局:变量定义、函数声明     一段<script>
    • 函数:变量定义、函数声明、this、arguments      函数
      注意:"函数声明"和"函数表达式"的区别
    	// 执行上下文
        /*
            全局:
                变量提升:var a = undefined 注意a = 100的赋值并不提前
                函数声明提前
        */
        console.log(a);  // undefined
        var a = 100;
    
        fn('zhangsan');  // 'zhangsan' 20
        function fn(name) {
            age = 20;
            console.log(name, age);
            var age;
    
            bar(100);  // 100
    
            function bar(num) {
                console.log(num);
            }
        }
    	
    	// "函数声明"和"函数表达式"的区别
        fn();  // 函数声明会提前,不报错
        function fn() {
            // 声明
        }
    
        fn1();  // 函数表达式不会提前,报错
        var fn1 = function() {
            // 函数表达式
        }
    
  • this

    • this要在执行时才能确认值,定义时无法确认
    	// this
        var a = {
            name: 'A',
            fn: function() {
                console.log(this.name);
            }
        };
        a.fn();  // A     this === a
        a.fn.call({name: 'B'});  // B     this === {name: 'B'}
        var fn1 = a.fn;
        fn1();  // 输出值为空     this === window
    

    4种执行方式

    • 作为构造函数执行
    • 作为对象属性执行
    • 作为普通函数执行
    • call apply bind
    	// 作为构造函数执行
        function Foo(name) {
            // this = {};
            this.name = name;
            // return this;
        }
        var f = new Foo('zhangsan');
        console.log(f);  // Foo {name: 'zhangsan'}
        // 作为对象属性执行
        var obj = {
            name: 'A',
            printName: function() {
                console.log(this.name);
            }
        }
        obj.printName();  // A
        // 作为普通函数执行
        function fn() {
            console.log(this);
        }
        fn();  // Window
        // call apply bind
        function fn1(name, age) {
            alert(name);
            console.log(this);  // {x: 100}
        }
        fn1.call({x: 100}, 'zhangsan', 20); // this === {x: 100}
        var fn2 = function (name, age) {
            alert(name);
            console.log(this);  // {y: 200}
        }.bind({y: 200});
        fn2('zhangsan', 20); // this === {y: 200}
    
  • 作用域

    • 没有块级作用域
    • 只有函数和全局作用域
    	// 无块级作用域
        // if(true) {
        //     var name = 'zhangsan';
        // }
        // 与上等同,推荐下面这种写法
        var name;
        if(true) {
            name = 'zhangsan';
        }
        console.log(name); // zhangsan
    
        // 只有函数和全局作用域
        var a = 100;
        function fn() {
            var a = 200;
            console.log('fn', a);  // fn 200
        }
        console.log('global', a);  // global 100
        fn();
    
  • 作用域链

    • 当前作用域没有没有定义的变量,即“自由变量”,“自由变量”需要在父级作用域中找到
    • 作用域链是在预编译阶段形成的
    	// 作用域链
        // demo1
        var a = 100;
        function fn() {
            var b = 200;
            // 当前作用域没有没有定义的变量,即“自由变量”
            console.log(a);  // 100 在父级作用域中找到
            console.log(b);  // 200
        }
        fn();
        // demo2
        var a = 100;
        function F1() {
            var b = 200;
            function F2() {
                var c = 300;
                console.log(a);  // 100   a 是自由变量
                console.log(b);  // 200   b 是自由变量
                console.log(c);  // 300
            }
            F2();
        }
        F1();
    
  • 闭包 – 两个使用场景

    • 函数作为返回值
    • 函数作为参数传递
    	// 函数作为返回值
        function F1() {
            var a = 100;
    
            // 返回一个函数(函数作为一个返回值)
            return function() {
                console.log(a);  // 自由变量,父级作用域寻找
            }
        }
        // f1 得到一个函数
        var f1 = F1();
        var a = 200;
        f1();  // 100
        // 函数作为参数传递
        function F1() {
            var a = 100;
    
            // 返回一个函数(函数作为一个返回值)
            return function() {
                console.log(a);  // 自由变量,父级作用域寻找
            }
        }
        // f1 得到一个函数
        var f1 = F1();
        function F2(fn) {
            var a = 200;
            fn();
        }
        F2(f1);  // 100
    

3-3 题目解答

  • 说一下对变量提升的理解
    • 变量定义
    • 函数声明(注意和函数表达式的区别)
    • demo同3-2的执行上下文
  • 说明this几种不同的使用场景
    4种执行方式
    • 作为构造函数执行
    • 作为对象属性执行
    • 作为普通函数执行
    • call apply bind
  • 创建10个<a>标签,点击的时候弹出来对应的序号
    	// 问题:创建10个<a>标签,点击的时候弹出来对应的序号
        // 这是一个错误的写法,无论点击哪个标签弹出的序号都是10
        var i, a;
        for(i = 0; i < 10; i++) {
            a = document.createElement('a');
            a.innerHTML = i + '<br>';
            a.addEventListener('click', function(e) {
                e.preventDefault();
                alert(i);  // 自由变量,要去父作用域获取值
            });
            document.body.appendChild(a);
        }
        这是正确的写法
        var i, a;
        for(i = 0; i < 10; i++) {
            (function(i) {
                // 函数作用域
                a = document.createElement('a');
                a.innerHTML = i + '<br>';
                a.addEventListener('click', function(e) {
                    e.preventDefault();
                    alert(i);  // 自由变量,要去父作用域获取值
                });
                document.body.appendChild(a);
            })(i);
        }
    
  • 如何理解作用域
    • 自由变量
    • 作用域链,即自由变量的查找
    • 闭包的两个使用场景
  • 实际开发中闭包的作用
    	// 问题:闭包在实际开发中的应用:主要用于封装变量,收敛权限
        function isFirstLoad() {
            var _list = [];  // 在函数 isFirstLoad 外面,根本不可能修改掉 _list 的值
            return function(id) {
                if(_list.indexOf(id) >= 0) {
                    return false;
                }
                else {
                    _list.push(id);
                    return true;
                }
                
            }
        }
        // 使用
        var firstLoad = isFirstLoad();
        console.log(firstLoad(10));  // true
        console.log(firstLoad(10));  // false
        console.log(firstLoad(20));  // true
        console.log(firstLoad(10));  // false
    

4-异步和单线程

4-1 题目

  • 同步和异步的区别是什么?分别举一个同步和异步的例子
  • 一个关于setTimeout的笔试题
  • 前端使用异步的场景有哪些

4-2 知识点

  • 什么是异步(对比同步)
    	// 什么是异步
        console.log(100);
        setTimeout(function() {
            console.log(200);
        }, 1000);
        console.log(300);
        // 执行结果:100  300  200
        // 对比同步
        console.log(100);
        alert(200);  // 用户点击确认之后才会输出300
        console.log(300);
    
  • 前端使用异步的场景
    • 何时需要异步
      • 在可能发生等待的情况
      • 等待过程中不能像alert一样阻塞程序运行
      • 因此,所有的“等待的情况”都需要异步
    • 前端使用异步的场景
      • 定时任务:setTimeout, setInterval
      • 网络请求:ajax请求, 动态<img>加载
      • 事件绑定
    	// ajax请求代码示例
        console.log('start');
        $.get('http://ku.qingnian8.com/wxList.php', function(res) {
            console.log(res);
        });
        console.log('end');
        // <img>加载示例
        console.log('start');
        let img = document.createElement('img');
        img.onload = function() {
            console.log('loaded');
        }
        img.src = 'https://pics2.baidu.com/feed/d1160924ab18972bbbff10c7d27c63829f510a35.jpeg@f_auto?token=cce7c10b15dc1d84cb721c44a961da08';
        document.body.appendChild(img);
        console.log('end');
        // 事件绑定示例
        console.log('start');
        document.getElementById('btn1').addEventListener('click', function() {
            alert('clicked');
        });
        console.log('end');
        // 输出结果 start end start end start end loaded 网络请求获得的数据
    
  • 异步和单线程
    	// 异步和单线程
        console.log(100);
        setTimeout(function() {
            console.log(200);
        });
    
    • 上述程序执行过程如下:
      • 执行第一行,打印100
      • 执行setTimeout后,传入setTimeout的函数会被暂存起来,不会立即执行(单线程的特点,不能同时干两件事)
      • 执行最后一行,打印300
      • 待所有程序执行完,处于空闲状态时,会立马看有没有暂存起来的要执行。
      • 发现暂存起来的setTimeout中的函数无需等待时间,就立即执行。

4-3 题目解答

  • 同步和异步的区别是什么?分别举一个同步和异步的例子
    • 同步会阻塞代码执行,而异步不会
    • alert是同步,setTimeout是异步
  • 一个关于setTimeout的笔试题
    	// 问题:一个关于setTimeout的笔试题
        console.log(100);
        setTimeout(function() {
            console.log(200);
        });
        console.log(300);
        setTimeout(function() {
            console.log(400);
        }, 1000);
        console.log(500);
        // 输出结果:100 300 500 200 400
    
  • 前端使用异步的场景有哪些
    • 定时任务:setTimeout, setInterval
    • 网络请求:ajax请求, 动态<img>加载
    • 事件绑定

5-JS常用内置对象API

5-1 题目

  • 获取2017-06-10格式的日期
  • 获取随机数,要求是长度一致的字符串格式
  • 写一个能遍历对象和数组的通用forEach函数

5-2 知识点

  • 日期API
    	// 日期API
        Date.now();  // 获取当前时间戳--毫秒数
        let date = new Date();  // 获取系统当前时间--Fri Oct 14 2022 16:14:17 GMT+0800 (中国标准时间)
        date.getTime();  // 获取时间戳--毫秒数
        // 获取日期分量API
        let year = date.getFullYear();  // 年
        let month = date.getMonth();  // 月(0 - 11)
        let date1 = date.getDate();  // 日(1 - 31)
        let xingqi = date.getDay();  // 星期(0 - 6)
        let hour = date.getHours();  // 小时(0 - 23)
        let minute = date.getMinutes();  // 分钟(0 - 59)
        let second = date.getSeconds();  // 秒 (0 - 59)
        let millisecond = date.getMilliseconds();  // 毫秒(0 - 59)
        // 设置日期分量API
        date.setFullYear(year + 1);
        date.setMonth(month + 1);
        date.setDate(date1 + 1);
        date.setHours(hour + 1);
        date.setMinutes(minute + 1);
        date.setSeconds(second + 1);
        date.setMilliseconds(millisecond + 1);
    
  • MathAPI
    • 获取随机数Math.random()
  • 数组API
    • forEach 遍历所有元素
    	let arr = [1, 2, 3];
        arr.forEach(function(item, index) {
            // 遍历数组的所有元素
            console.log(index, item);
        });
        /*
            输出结果
            0 1
            1 2
            2 3
        */
    
    • every 判断所有元素是否都符合条件
    	let arr = [1, 2, 3, 4];
        let result = arr.every(function(item, index) {
            // 用来判断所有的数组元素,都满足一个条件
            if(item < 4) {
                return true;
            }
        });
        console.log(result);  // false
    
    • some 判断是否有至少一个元素符合条件
    	let arr = [1, 2, 3, 4];
        let result = arr.some(function(item, index) {
            // 用来判断所有的数组元素,只要有一个满足条件即可
            if(item < 2) {
                return true;
            }
        });
        console.log(result);  // true
    
    • sort 排序:将数组排序,并将排序后的数组返回
    	let arr = [1, 4, 2, 3, 5];
        let result = arr.sort(function(a, b) {
            // 升序
            // return a - b;
    
            // 降序
            return b - a;
        });
        console.log(arr);  // [5, 4, 3, 2, 1]
    
    • map 对元素重新组装,生成新数组
    	let arr = [1, 2, 3, 4];
        let result = arr.map(function(item, index) {
            // 将数组元素重新组装,并返回
            return '<b>' + item + '</b>';
        });
        console.log(result);  // ['<b>1</b>', '<b>2</b>', '<b>3</b>', '<b>4</b>']
    
    • filter 过滤符合条件的元素
    	let arr = [1, 2, 3, 4];
        let result = arr.filter((item, index) => {
            // 通过某一个条件过滤数组
            if(item >= 2) {
                return true;
            }
        });
        console.log(result);  // [2, 3, 4]
    
  • 对象API
    	let obj = {
            x: 100,
            y: 200,
            z: 300
        };
        for(let key in obj) {
            // 注意这里的 hasOwnProperty,在讲原型链的时候讲过了
            if(obj.hasOwnProperty(key)) {
                console.log(key, obj[key]);
            }
        }
        /*
            输出结果
            x 100
            y 200
            z 300
        */
    

5-3 题目解答

  • 获取2017-06-10格式的日期
    	// 问题:获取2022-10-14格式的日期
        function formatDate(date) {
            if(!date) {
                date = new Date();
            }
            let year = date.getFullYear();
            let month = date.getMonth() + 1;
            let date1 = date.getDate();
            if(month < 10) {
                // 强制类型转焕
                month = '0' + month;
            }
            if(date1 < 10) {
                // 强制类型转焕
                date1 = '0' + date1;
            }
            // 强制类型转焕
            return year + '-' + month + '-' + date1;
        }
        let date = new Date();
        console.log(formatDate(date));  // 2022-10-14
    
  • 获取随机数,要求是长度一致的字符串格式
    	// 问题:获取随机数,要求是长度一致的字符串格式
        let random = Math.random();
        random = random + '0000000000';  // 后面加上10个零
        random = random.slice(0, 10);
        console.log(random);
    
  • 写一个能遍历对象和数组的通用forEach函数
    	// 问题:写一个能遍历对象和数组的通用forEach函数
        function forEach(obj, fn) {
            // 准确判断是不是数组
            if(obj instanceof Array) {
                obj.forEach(function(item, index) {
                    fn(index, item);
                });
            }
            // 不是数组就是对象
            else {
                for(let key in obj) {
                    if(obj.hasOwnProperty(key)) {
                        fn(key, obj[key]);
                    }
                }
            }
        }
        let arr = [1, 2, 3];
        // 注意,这里参数的顺序换了,为了和对象的遍历格式一致
        forEach(arr, function(index, item) {
            console.log(index, item);
        });
        /*
            输出结果
            0 1
            1 2
            2 3
        */
        let obj = {x: 100, y: 200};
        forEach(obj, function(key, val) {
            console.log(key, val);
        });
        /*
            输出结果
            x 100
            y 200
        */
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值