• js基础知识


    js复习

    js知识点介绍

    基础知识

    1、原型、原型链

    2、作用域、闭包

    3、异步单线程

    jsAPI

    1、DOM操作

    2、AJax

    3、事件绑定

    开发环境

    1、版本管理

    2、模块化

    3、打包工具

    运行环境

    1、页面渲染

    2、性能优化

    一、原型和原型链

    1、构造函数

    <script>
        function Foo(name,age){
            this.name = name;
            this.age = age;
            this.class = 'class-1';
            // return this; 默认有这一行
        }
        var f = new Foo('zhangsan',20);
        var f1 =new Foo('lisi',22); //创建多个对象
    </script>
    

    2、构造函数--扩展

    • var a = {}其实是var a = new Object()的语法糖
    • var a = []其实是var a = new Array()的语法糖
    • function Foo(){...}其实是var Foo = new Function(...)的语法糖
    • 使用instanceof判断一个函数是否是一个变量的构造函数
    • 判断一个变量是否为“数组”
    • 变量 instanceof Array

    3、原型规则和示例

    5条原型规则

    • 原型规则是学习原型链的基础

    • 1、所有的引用类型(数组、对象、函数)都具有对象特性,即自由扩展特性(除了"null"以外)

        var obj = {};
        obj.a = 100;
        var arr = [];
        arr.a = 100;
        function fn(){};
        fn.a = 100;
      
    • 2、所有的引用类型(数组、对象、函数),都有一个__proto__属性,属性值是一个普通对象

        console.log(obj.__proto__);
        console.log(arr.__proto__);
        console.log(fn.__proto__);
      
    • 3、所有的函数,都有一个prototype属性,属性值也是一个普通对象。

        console.log(fn.prototype)
      
    • 4、所有的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的prototype属性值

    • __proto__隐式类型原型

    • prototype显示类型原型

        console.log(obj.__proto__ === Object.prototype)//true
      
    • 5、当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。

        //构造函数
        function Foo(name,age){
            this.name = name;
        }
        Foo.prototype.alertName = function(){
            alert(this.name);
        }
        //创建实例
        var f = new Foo('zhangsan');
        f.printName = function(){
            console.log(this.name);
        }
        //测试
        f.printName();//zhangsan
        f.alertName(); //zhangsan
      

    循环对象自身的属性 hasOwnProperty

    var item;
    for(item in f){
    	//高级浏览器已经在for in 屏蔽了来自原型的属性
    	if(f.hasOwnProperty(item)){
    		console.log(item);//name  printName
    	}
    }
    

    4、原型链

    5、instanceof

    • f instanceof Foo的判断逻辑是
    • f的__proto__一层一层往上,能否对应到Foo.prototype再试着判断f instanceof Object

    问题

    1、如何准确的判断一个变量是数组类型

    var arr=[];
    arr instanceof Array; //true
    typeof arr;  //Object,typeof是无法判断是否是数组的
    

    2、写一个原型链继承的例子

    //动物
    function Animal() {
    	this.eat = function(){
    		console.log('animal eat');
    	}
    }
    //狗
    function Dog(){
    	this.bark = function(){
    		console.log('dog bark');
    	}
    }
    Dog.prototype = new Animal();
    var hashiqi = new Dog();//哈士奇
    

    3、描述new 一个对象的过程

    • 创建一个新对象

    • this指向这个新对象

    • 执行代码即对this赋值

    • 返回this

        //构造函数
        function Foo(name,age){
            this.name = name;
            this.age = age;
            this.class = 'class-1';
        }
        var f = new Foo('zhangsan',20)
      

    4、写一个dom查询的例子

    function Elem(id){
            this.elem = document.getElementById(id);
        }
        Elem.prototype.html = function(val){
            var elem = this.elem;
            if(val){
                elem.innerHTML = val;
                return this;//链式操作
            }else {
                return elem.innerHTML;
            }
        }
        Elem.prototype.on = function(type,fn){
            var elem = this.elem;
            elem.addEventListener(type,fn);
            return this;
        }
        var div1 = new Elem('div1');
        div.html('<p>hello world').on('click',function(){
            alert('clicked')
        }).html('<p>javascript</p>')
    

    二、作用域、闭包

    1、执行上下文

    • 1、范围:一段<script>或者一个函数

    • 2、全局:变量定义、函数声明一段<script>

    • 3、函数:变量定义、函数声明、this.argument函数

    • ps:注意函数声明和函数表达式的区别

        console.log(a);//undefined
        var a = 100;//函数声明
        fn('zhangsan'); //'zhangshan' 20
        function fn(name){//函数表达式
        	age = 20;
        	console.log(name,age)
        	var age;
        }
      

    2、this

    • this要在执行时才能确定值,定义时无法确定

        var a = {
        	name: 'A',
        	fn:function(){
        		console.log(this.name);
        	}
        }
        a.fn();//this === a
        a.fn.call({name:'B'});//this === {name:'B'}
        var fn1 = a.fn;
        fn1(); //this === window;
      
    • (1)、作为构造函数执行

        Function Foo(name){
        	this.name = name;
        }
        var f = new Foo('zhangsan')
      
    • (2)、作为对象属性执行

        var obj = {
        	name: 'A',
        	printName:function(){
        		console.log(this.name)
        	}
        }
        obj.printName();
      
    • (3)、作为普通函数执行

        function fn(){
        	console.log(this)
        }
        fn();
      
    • (4)、callapplyind

        function fn1(name,age){
        	alert(name);
        	console.log(this);
        }
        fn1.call({x:100},'zhangsan',20)
        fn1.apply({x:100},['zhangsan',20])
        var f2 = function (name,age){
        	alert(name);
        	console.log(this);
        }.bind({y:200});
        fn2('zhangsan',20)
      

    3、作用域

    • 1、没有块级作用域

    • 2、只有函数和全局作用域

        //无块级作用域
        if(true){
        	var 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();
      

    4、作用域链

    var a = 100;
    function fn(){
    	var b = 200;
    	//当前作用域没有定义的变量,即自由变量
    	console.log(a)//100
    	console.log(b)//200
    }
    fn()
    

    5、闭包

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

    6、闭包的使用场景

    • 1、函数作为返回值

    • 2、函数作为参数传递

        function F1(){
        	var a = 100;
        	return function(){
        		console.log(a)
        	}
        }
        var f1 = F1();
        function F2(fn){
        	var a = 200;
        	fn();
        }
        F2(f1);//100
      

    问题

    1、说一下变量提升的理解

    • 变量升级 变量是在存储信息的容器

    • 函数声明(注意和函数表达式的区别)

    • 变量提升就是,在变量的作用域内,不管变量在何处声明,都会提升到作用域的顶部,但是变量初始化的顺序不变。

        function test(){
        	a = 1;
        	b = 2;
        	var a b;
        	console.log(a)
        	console.log(b)
        }
      

    2、说明this几种不同的场景

    • 1、构造函数执行
    • 2、作为对象属性执行
    • 3、作为普通函数执行
    • 4、call、apply、bind

    3、如何理解作用链

    • 自由变量
    • 作用域链,即自由变量的查找
    • 闭包的两个场景

    实际开发中闭包的应用

    //闭包实际应用中主要封装变量,收敛权限
    function isFirstLoad(){
    	var _list = [];
    	return function(id){
    		if(_list.indexOf(id)>=0){
    			return false;
    		}else {
    			_list.push(id);
    			return true;
    		}
    	}
    }
    //使用
    var firstLoad = isFirstLoad();
    firstLoad(0);//true
    firstLoad(10);//false
    firstLoad(20);//true
    //你在isFirstLoad函数外面,根本不可能修改掉_list的值
    

    三、异步和单线程

    • 什么是异步(对比异步)
    • 前端使用用异步的场景
    • 异步和单线程

    1、什么是异步

    console.log(100);
    setTimeout(function(){
    	console.log(200)
    },1000);
    console.log(300);
    //100 300 200顺序
    //对比同步 同步会有阻塞
    console.log(100);
    alert(200);//几秒中之后单击确认
    console.log(300);
    //100 200 300
    

    2、何时需要异步

    • 在可能发生等待的情况
    • 等待过程不能像alert一样阻塞程序运行,因此,所以的“等待的情况”都需要异步。

    3、前端使用异步的场景

    • 1、定时任务:setTimeout、setInverval

    • 2、网络请求:ajax请求、动态加载

    • 3、事件绑定

    • ajax请求代码示例

        console.log('start')
        $.get('/data.json',function(data1){
        	console.log(data1);
        }
        console.log('end');//start end data1
      
    • 加载示例

        cosnole.log('start');
        var img = document.createElement('img');
        img.onload = function(){
        	console.log('loaded')
        }
        img.src = '/xxx.png';
        console.log('end');//start end loaded
      
    • 事件绑定示例

        cosnole.log('start');
        document.getElementById('btn1').addEventListener('click',function(){
        	alert('clicked');
        })
        console.log('end');
        //start end clicked
      

    4、异步和单线程

    	console.log(100);
    	setTimeout(function(){
    		console.log(200);
    	})
    	console.log(300);
    	//100 300 200
    
    • 1.执行第一行,打印100。
    • 2.执行setTimeout后传入setTimeout的函数会被暂存起来,不会立即执行(单线程的特点,不能同时干两件事)。
    • 3.执行最后一行打印300。
    • 4.待所有程序执行完,处于空闲状态时,会立马看有没有暂存起来的要执行。
    • 5.发现暂存起来的setTimeout中的函数无需等待时间,就立即来过来执行。

    问题

    1、同步和异步区别是什么

    • 1.同步会阻塞代码执行,而异步不会
    • 2.alert是同步,setTimeout是异步

    2、一个关于setTimeout的笔试题

    console.log(1);
    setTimeout(function(){
    	console.log(2);
    },0)
    console.log(3);
    setTimeout(function(){
    	console.log(4)
    },1000)
    console.log(5);
    //1 3 5 2 4
    

    3、前端使用异步的场景有哪些

    • 定时任务:setTimeout、setInverval
    • 网络请求:ajax请求、动态加载
    • 事件绑定

    四、其他知识

    知识点

    • 日期、Math、数组API、对象API

    1、日期

    • Date.now() //获取当前时间的毫秒数
    • var dt = new Date();
    • dt.getTime(); //获取毫秒数
    • dt.getFullYear(); //年
    • dt.getMonth();//月(0-11)
    • dt.getDate(); //日(0-31)
    • dt.getHours();//小时(0-23)
    • dt.getMinutes();//分钟(0-59)
    • dt.getSeconds();//秒(0-59)

    2、Math

    • 获取随机数Math.random()

    3、数组API

    • forEach 遍历所有元素

    • every 判断所有元素是否都符合条件

    • some 判断是否有至少一个元素符合条件

    • sort 排序

    • map 对元素重新组装,生成新数组

    • filter 过滤符合条件的元素

    • forEach

        var arr = [1,2,3]
        arr.forEach(function(item,index){
            //遍历数组的所有元素
            console.log(index,item)
        })
      
    • every

        var arr = [1,2,3];
        var result = arr.every(function(item,index){
            //用来判断所有的数组元素,都满足一个条件
            if(item<4){
                return ture
            }
        })
        console.log(result)//true
      
    • some

        var arr = [1,2,3];
        var result = arr.some(function(item,index){
            //用来判断所有的数组元素,只要有一个满足条件即可
            if(item<2){
                return true
            }
        })
        console.log(result)//true
      
    • sort

        var arr = [1,4,2,3,5];
        var arr2 = arr.sort(function(a,b){
            //从小到大排序
            return a-b
            //从大到小的排序
            return b-a
        })
        console.log(arr2);
      
    • map

        var arr = [1,2,3,4];
        var arr2 = arr.map(function(item,index){
            //将元素重新组装,并返回
            return '<br>'+item+'</b>'
        })
        console.log(arr2)
      
    • filter

        var arr = [1,2,3];
        var arr2 = arr.filter(function(item,index){
            //通过某一个条件过滤数组
            if(item>=2){
                return true
            }
        })
        console.log(arr2);//2 3
      

    4、对象API for in

    var obj = {x:100,y:200,z:300};
    var key;
    for(key in obj){
        if(obj.hasOwnProperty(key)){
            console.log(key,obj[key])
        }
    }
    //x, 100;y ,200;z,300
    

    解题

    1、获取2019-02-16(当前时间)

    	function formatDate(dt) {
    		if(!dt){
    			dt = new Date();
    		}
    		var year = dt.getFullYear();
    		var month = dt.getMonth()+1;
    		var date = dt.getDate();
    		if(month < 10){
    			//强制类型转换
    			month = '0'+month;
    		}
    		if(date <10){
    			//强制类型转换
    			date = '0'+date;
    		}
    		//强制类型转换
    		return year + '-'+month + '-'+date;
    	}
    	var dt = new Date();
    	var formatDate = formatDate(dt);
    	console.log(formatDate);//2019-02-16
    

    2、获取随机数,要求是长度一致的字符串格式

    var random = Math.random();
    random = random + '0000000000'//后面加上10个0
    random = random .slice(0,10);
    console.log(random)
    

    3、写一个能遍历对象和数组的forEach函数

    function forEach(obj,fn){
    	var key;
    	if(obj instanceof Array){
    		//准确判断是否是数组
    		obj.forEach(function(item,index){
    			fn(index,item);
    		})
    	}else {
    		//不是数组就是对象
    		for(key in obj){
    			if(obj.hasOwnProperty(key)){
    				fn(key,obj[key])
    			}
    		}
    	}
    }
    var arr = ['苹果','香蕉','梨'];
    //注意,这里的参数的顺序换了,为了和对象的遍历格式一致
    forEach(arr,function(index,item){
    	console.log(index,item)
    	// 0 "苹果"
    	// 1 "香蕉"
    	// 2 "梨"
    })
    var obj = {x:100,y:200};
    forEach(obj,function(key,value){
    	console.log(key,value)
    	// x 100
    	// y 200
    })
  • 相关阅读:
    状态模式
    简单密码再次加密
    服务层定义自己的服务异常类
    必备网络基础知识(持续补充)
    MongoDB基础入门
    Git命令整理
    算法基础(四)
    RabbitMQ消息队列
    设计模式(23种)
    二叉树知识点
  • 原文地址:https://www.cnblogs.com/DCL1314/p/10393121.html
Copyright © 2020-2023  润新知