js基础知识

js复习

js知识点介绍

基础知识

一、原型、原型链

二、做用域、闭包

三、异步单线程

jsAPI

一、DOM操做

二、AJax

三、事件绑定

开发环境

一、版本管理

二、模块化

三、打包工具

运行环境

一、页面渲染

二、性能优化

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>

二、构造函数--扩展

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

三、原型规则和示例

5条原型规则

  • 原型规则是学习原型链的基础
  • 一、全部的引用类型(数组、对象、函数)都具备对象特性,即自由扩展特性(除了"null"之外)javascript

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

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

    console.log(fn.prototype)
  • 四、全部的引用类型(数组、对象、函数),__proto__属性值指向它的构造函数的prototype属性值
  • __proto__隐式类型原型
  • prototype显示类型原型java

    console.log(obj.__proto__ === Object.prototype)//true
  • 五、当试图获得一个对象的某个属性时,若是这个对象自己没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。ajax

    //构造函数
      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
    }
}

四、原型链

五、instanceof

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

问题

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

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

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

//动物
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();//哈士奇

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

  • 建立一个新对象
  • this指向这个新对象
  • 执行代码即对this赋值
  • 返回thisjson

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

四、写一个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>')

2、做用域、闭包

一、执行上下文

  • 一、范围:一段<script>或者一个函数
  • 二、全局:变量定义、函数声明一段<script>
  • 三、函数:变量定义、函数声明、this.argument函数
  • ps:注意函数声明和函数表达式的区别api

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

二、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)、call\apply\bind

    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)

三、做用域

  • 一、没有块级做用域
  • 二、只有函数和全局做用域

    //无块级做用域
      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();

四、做用域链

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

五、闭包

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

六、闭包的使用场景

  • 一、函数做为返回值
  • 二、函数做为参数传递

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

问题

一、说一下变量提高的理解

  • 变量升级 变量是在存储信息的容器
  • 函数声明(注意和函数表达式的区别)
  • 变量提高就是,在变量的做用域内,无论变量在何处声明,都会提高到做用域的顶部,可是变量初始化的顺序不变。

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

二、说明this几种不一样的场景

  • 一、构造函数执行
  • 二、做为对象属性执行
  • 三、做为普通函数执行
  • 四、call、apply、bind

三、如何理解做用链

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

实际开发中闭包的应用

//闭包实际应用中主要封装变量,收敛权限
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的值

3、异步和单线程

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

一、什么是异步

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

二、什么时候须要异步

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

三、前端使用异步的场景

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

  • 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

四、异步和单线程

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.同步会阻塞代码执行,而异步不会
  • 2.alert是同步,setTimeout是异步

二、一个关于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

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

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

4、其余知识

知识点

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

一、日期

  • 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)

二、Math

  • 获取随机数Math.random()

三、数组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

四、对象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

解题

一、获取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

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

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

三、写一个能遍历对象和数组的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
})
相关文章
相关标签/搜索