博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript 学习笔记
阅读量:6213 次
发布时间:2019-06-21

本文共 9190 字,大约阅读时间需要 30 分钟。

1. typeof判断类型

javascript 的原始类型包括:

两个未定义类型:undefined,null;

常用三种:number boolean string

JavaScript的引用类型 object

其中object包括了:function array date

 

2

 

问题三:

3.1 如何判断一个变量是数组类型

3.2 写一个原型链继承的例子

3.3 描述 new 一个对象的过程

3.4 zepto(或其他框架)源码中如何使用原型链

 背景知识介绍:

// 构造函数 首字母大写 类似于模板function Foo(name,age){    this.name = name;    this.age = age;    this.class = 'class-1';    // return this //默认有这一行} // 每次new一个类的时候,this先变成空对象,然后在赋值this的name等值,最后在return 出来给new出来的f,则f.name=zhangsanvar f = new Foo('zhangsan',20); //创建多个对象var f1 = new Foo('lisi',22);

所有的引用类型(数组/对象/函数),都具有对象特性,即可以自由扩展属性(除了null以外)如 var obj = {}; obj.a=1000;

所有的引用类型(数组、对象、函数),都有一个 _proto_ (隐式原型)属性,属性值是一个普通的对象。

所有的引用类型(数组、对象、函数),_propto_属性值指向它的构造函数的 “protptype”属性值

其中this指向对象本身。

上面f有三个属性: name,alertName,printName;

为了拿到它自身的属性name,printName:

 

例如在实例f中调用,本来没有定义过的 f.toString()方法,就按照下图所示,一级一级原型链的往上找:(注意Object的原型是null,避免导致死循环)

 

 instanceOf 用于判断 引用类型 属于哪个 构造函数的方法;

判断f是否输入对象,首先根据原型链找到父级 Foo,无法判断,则再找上一级,一直找到Object

 

 

或者把Animal类的方法提取出来:

function Animal(){}Animal.prototype.eat = function(){    console.log('eat');}function Dog(){    this.bark = function(){        console.log('dog bark');    }}Dog.prototype = new Animal();var hashiqi = new Dog();hashiqi.bark();hashiqi.eat();

 

 

写一个原型继承的例子:

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');div1.html('

hello

');div1.on('click',function(){ alert('clicked');})/*可以链式操作:div1.html('

hello

').on('click',function(){ alert('clicked');})*/

 

问题四:

4.1 说一下对变量提升的理解

4.2 说明this几种不同的使用场景

4.3 创建10个<a>标签,点击的时候弹出来对应的序号

4.4 如何理解作用域

4.5 实际开发过程中闭包的应用

=======================

4.1.1 执行上下文

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

全局:变量定义/函数声明

函数:变量定义,函数声明/this/arguments

console.log(a); //undefinedvar a = 100;fn('zhangsan'); //'zhangsan' 20function fn(name){    age = 20;    console.log(name,age);    var age;}

函数和变量的声明先提取到前面,不同的是变量的提升会用undefined占位,如 var a = undefined 占位,尚未执行到var a = 100 赋值;

而函数声明会把整个函数先提取到前面:在执行到函数 fn(‘zhangsan’)的时候 在看函数内部: 首先提升age变量;

 

4.2 this要在执行时才能确认值,定义时无法确认:

var a = {    name:"A",    fn:function (){        console.log(this.name);    }}a.fn(); //this === Aa.fn.call({name:"B"}) //this === {name:"B"}var fn1 = a.fn;fn1() // this === window

 this:

作为构造函数执行:一般在实例化时确认;

作为对象属性执行:类似于上面的例子,一般时对象的属性值;

作为普通函数执行:一般是window

call apply bind:一般是会被改变this的指向;

function Foo(name){    this.name = name;//这里的this表示实例化的f的属性:f.name}var f = new Foo('zhangsan');=============================var obj = {    name:"aa",    printName:function(){        console.log(this.name);//这里的this表示obj    }}obj.printName();=============================function fn(){    console.log(this); //this===window}fn();=============================function fn1(name,age){    alert(name);    console.log(this);//下面使用的是call,所以改变了this的指向,指向了call的第一个对象}//fn1.call({x:1},'zhangsan',20);fn1.apply({x:1},['zhangsan',20]);//apply 和call类似,只不过第二个参数变成了数组==============================var fn2 = function(name,age){
//bind方法必须是函数表达式的形式 alert(name); console.log(this);//如果不做call applay或bind的操作,这里的this指向window}.bind({y:200});//bind改变this的指向fn2('zhangsan',20);

 作用域:

//无块级作用域,所以外面的name可以拿到这个数据     if(true){    var name = "zhangsan"}console.log(name);==========//函数和全局作用域var a = 100;//全局作用域function fn(){    var a = 200;//函数作用域    console.log('fn',a);}function fn1(){    console.log('fn1',a);}console.log('global',a);//global 100fn();// fn 200fn1();// fn1 100

 作用域链:自由变量一直往上找

//当前作用域没有定义的变量,即自由变量//注意的是定义的时候,而不是执行的时刻var a = 100;function F1(){    var b = 200;    function F2(){        var c = 300;        console.log(a);        console.log(b);        console.log(c);    }    F2();}F1(); //结果是 100 200 300

 

{    var a = 100;}console.log(a); //可以获取到afunction fn2(){    var a = 100;}fn2();console.log(a);//获取不到a,是函数内部的局部变量

4.3 创建10个<a>标签,点击的时候弹出来对应的序号

因为变量i放在了全局作用域,每次循环之执行后,都会覆盖之前的值。

而上述方法,每次循环都在一个函数体里,相当于局部作用域,i都是独立的。

 

5. 异步

5.1 同步和异步的区别是什么?分别举一个同步和异步的例子

5.2 一个关于setTimeout的笔试题;

5.3 前端使用异步的场景有哪些;

(1)定时任务:setTimeout setInterval

(2)网络请求: ajax请求,动态<img>标签

(3)事件绑定

例如:

console.log('start');var img = document.createElement('img');img.onload = function (){    console.log('loaded');//图片加载完才执行这里}console.log('end');

执行顺序为:

start--end--loaded

5.4 获取2017-02-01格式的日期(视频4-5)

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

5.6 写一个能遍历对象和数组的通用forEach函数

数组API:

forEach 遍历所有元素every 判断所有元素是否都符合条件some 判断是否有至少一个元素符合条件sort 排序map 对元素重新组装,生成新数组filter 过滤符合条件的元素
var arr = [1,2,3];arr.forEach((item,index)=>{    console.log(item);});==============var arr = [1,2,3,4];var result = arr.every((item,index)=>{    //用来判断所有的数组元素,都满足一个条件,只要一个不满足,则返回false    if(item<4){         return true     }})console.log(result);//false==============var arr = [1,2,3,4];var result = arr.some((item,index)=>{    //用来判断所有的数组元素,只要有一个满足条件即可    if(item<4){         return true     }})console.log(result);//true===============var arr = [1,4,3,5,2];var arr2 = arr.sort((a,b)=>{    return a - b;//从小到大排序    return b - a;//从大到小排序})console.log(arr2); ===============//map和forEach不同在于可以返回生成一个新的数组var arr = [1,2,3,4];var arr2 = arr.map((item,index)=>{    return ''+item+''})console.log(arr2);//[ "1", "2", "3", "4" ]============//类似的使用forEach则不会返回新数组var arr = [1,2,3,4];var arr2 = arr.forEach((item,index)=>{    return ''+item+''})console.log(arr); // [1,2,3,4]console.log(arr2);//undefined=============//类似的使用filter 也可以返回一个新的数组var arr = [1,2,3,4];var arr2 = arr.filter((item,index)=>{    if(item>2){        return true;    }})console.log(arr2);//[3,4]=============//对象apivar obj = {    x:100,    y:200,    z:300}var key;for(key in obj){    if(obj.hasOwnProperty(key)){
//这里表示是obj的原生属性而不是集成父级 console.log(key,obj[key]); }}

forEach:

 

6.1 通用事件绑定

//简单来写var btn  = document.getElementById('btn1');btn.addEventListener('click',function(event){    console.log('clicked')})//封装函数的形式function bindEvent(elem,type,fn){    elem.addEventListener(type,fn);}var a = document.getElementById('link1');bindEvent(a,'click',function(e){    e.preventDefault();//组织a标签的默认行为    alert('click');})

6.2 在一个不断动态增加<a>标签的区域,给a上绑定事件,如何做?

a1
a2
a3
a4
a5    ...

使用代理:也就是给包裹a标签的div增减点击的监听事件,如果点击的目标是a则触发事件。这样不用给每一项增加点击事件了。

var div1= document.getElementById('div1');div1.addEventListener('click',function(e){    var target = e.target;    if(target.nodeName === "A"){        alert(target.innerHTML)    }})

7 跨域。(所有的跨域请求必须经过信息提供方允许)

可以允许跨域的有三个标签:

<img src="xxx">, <link href="xxx">,<script src="xxx">

 

JSONP的工作原理: 

注意几点:

1. 允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,

这样客户端就可以随意定制自己的函数来自动处理返回数据了。
2. 请求服务端地址,会动态生成一个js文件,包含了一个客户端提供的回调函数。

也就是在服务器端返回的回调函数 让其执行。在客户端定义改回调函数。

3 服务器端设置可以跨域:

response.setHeader("Access-Control-Allow-Origin","http://a.com,http://b.com"); //允许的域名 或者是*response.setHeader("Access-Control-Allow-Headers","X-Requested-With"); //在服务器端判断request来自Ajax请求(异步)还是传统请求(同步): response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); //请求方式response.setHeader("Access-Control-Allow-Credentials","true"); //接受跨域的cookies

 

8 书写ajax的基本原理;

要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:

      (1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.

      (2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.

      (3)设置响应HTTP请求状态变化的函数.

      (4)发送HTTP请求.

      (5)获取异步调用返回的数据.

      (6)使用JavaScript和DOM实现局部刷新.

var xhr = new XMLHttpRequest();xhr.open("GET","/api",false);xhr.onreadystatechange = function(){ //onreadystatechange  每次状态改变所触发事件的事件处理程序。    //这里是函数异步执行    if(xhr.readyState == 4){           if(xhr.status == 200){  //status 从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)            alert(xhr.responseText); //responseText 从服务器进程返回数据的字符串形式。        }    }}xhr.send(null);//只有在使用send()方法之后,XMLHttpRequest对象的readyState//属性值才会开始改变,也才会激发readystatechange事件,并调用函数。

对于XmlHttpRequest的两个方法,open和send,其中open方法指定了:

a、向服务器提交数据的类型,即post还是get。
b、请求的url地址和传递的参数。
c、传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。
我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。
readyState       对象状态值
    0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
    1 (初始化) 对象已建立,尚未调用send方法
    2 (发送数据) send方法已调用,但是当前的状态及http头未知
    3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
    4 (完成) 数据接收完毕,此时可以通过通过responseXml和responseText获取完整的回应数据

9.   cokie 用于存储的缺点

1 存储量很小 只有4kb
2 所有的http请求都会带着,会影响获取资源的效率
3 api简单,需要封装才能使用 document.cookie="name="+username;

10  localStorage 和 sessionStorage

  • Html5专门为本地存储而设计,最大容量是5M
  • API简单易用 localStorage.setItem(key,value),localStorage.getItem(key)
  • 目前所有的浏览器中都会把localStorage的值类型限定为string类型
  • localStorage在浏览器的隐私模式下面是不可读取的
  • localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空

11 js 模块化的好处

比如上面三个js文件 逐层引用;

 使用方式:

所以用到模块化:

 

12

commonjs是用在服务器端的,同步的,如nodejs

amd, cmd是用在浏览器端的,异步的,如requirejs和seajs
其中,amd先提出,cmd是根据commonjs和amd基础上提出的。

12.1 AMD模式:

使用方式:

 

12.2 CommonJS 规范

CommonJS 属于 node.js 模块化规范,现在被大量用于前端,原因:
1 前端开发依赖的插件和库,都可以从npm中获取;
2 构建工具的高度自动化,使得使用npm的成本非常低;
3 CommonJS 不会异步加载JS,而是同步一次性的加载出来,

 

 需要异步加载js 使用AMD

使用了npm之后建议使用commonJS

转载于:https://www.cnblogs.com/xiaozhumaopao/p/10741075.html

你可能感兴趣的文章
EOJ Monthly 2018.1
查看>>
document.compatMode属性
查看>>
Servlet学习笔记
查看>>
CyclicBarrier的应用场景
查看>>
20172318 《程序设计与数据结构》第三周学习总结
查看>>
Windows下安装phpRedis扩展
查看>>
在Visual Studio中将现有.NET Framework项目迁移至.NET Core 1.1 Preview 1
查看>>
电子商城实录------载入数据库模型
查看>>
为什么在vue的组件中,data要用function返回对象呢?
查看>>
使用selenium模拟登陆点击登陆按钮
查看>>
ligerui tab 部分记载
查看>>
Service服务
查看>>
1060. Are They Equal (25)
查看>>
win10在当前目录下 打开cmd
查看>>
jquery.extend 与 jquery.fn.extend的区别和使用
查看>>
NFS存储服务器的部署流程
查看>>
计算机网络术语总结2
查看>>
一个超简单的马里奥游戏
查看>>
DLRS(深度学习应用于推荐系统论文汇总--2017年8月整理)
查看>>
c setjmp longjmp
查看>>