JS基础篇

typeof返回的数据类型

  • undefined
  • string
  • boolean
  • number
  • object
  • function
  • symbol

js数据类型

  • string 字符串
  • number 数字
  • boolean 布尔
  • Null 空
  • undefined 未定义
  • Object 引用类型
  • es6新增 symbol类型

”==”和“===”的区别

前者会强制转换类型 后者不会

有哪些强制类型转换和隐式类型转换

  • 强制:parseInt(),parseFloat(),Number()
  • 隐式:== ,!=

解决js兼容性问题

  • Ajax兼容
var xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft,XMLHTTP");
  • 获取键盘e.key信息
e.keyCode || e.which
  • 获取非行间样式
// IE:currentStyle[attr]
// 标准:getComputedStyle[attr]
function getStyle(obj, attr) {
    if (obj.currentStyle) {
        return obj.currentStyle[attr]
    } else {
        return getComputedStyle(obj, false)[attr];
    }
}
  • 事件监听和解绑
addEventListener() //普通
attachEvent() //IE
removeEventListener() //普通
detachEvent() //IE
  • 使用 event对象
function eventHandler(event) {
    event = event || window.event
}
  • 获取滚动条属性
var scrollTop = document.documentElment.scrollTop || document.body.scrollTop
  • 阻止浏览器默认行为
function eventHandler(event) {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
}
  • 事件冒泡
function eventHandler(event) {
    if (event.stopPropagation) {
        event.stopPropagation()
    } else {
        event.cancelBubble()
    }
}

事件流

冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。就子元素向父元素触发 捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。就是父元素向子元素触发 优点:(1)可以大量节省内存占用(2)可以实现当新新增对象时,无需在对其进行绑定

事件委托

可以为同样元素绑定多次同一事件 可以确定是冒泡还是捕获 动态创建元素,可以创建元素的函数体外部为其添加 把某个事件加到父元素上提高程序执行效率

浏览器的事件机制

事件捕获阶段---处于目标阶段---事件的冒泡阶段----事件的默认阶段

事件绑定和普通事件的区别

  • 普通添加事件的方法:
var btn = document.getElementById("ele");
btn.onclick = function(){
    alert(1);
}
btn.onclick = function(){
    alert(2);
}

执行上面的代码只会alert 2

  • 事件绑定方式添加事件:
var btn = document.getElementById("ele");
btn.addEventListener("click",function(){
    alert(1);
},false);
5btn.addEventListener("click",function(){
    alert(2);
},false);

执行上面的代码会先alert 1 再 alert 2

  • 普通添加事件的方法不支持添加多个事件,最下面的事件会覆盖上面的,而事件绑定 (addEventListener)方式添加事件可以添加多个。
  • addEventListener不兼容低版本IE
  • 普通事件无法取消(无函数方式取消,使用置空和置为false)
  • addEventLisntener还支持事件冒泡+事件捕获

eval的理解

  • 可以将字符串生成语句执行,一般执行动态js语句
  • eval的使用场合:有时候我们预先不知道要执行什么语句,只有当条件和参数给时才知到执行什么语句,这时候eval就派上用场了 eval和json.parse的谁更高效?
  • 是json.parse
  • 因为evel他是转化在解析而json.parse是直接解析
  • 应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。

数组的方法

  • push() 从队尾添加,改变原数组
  • pop() 移除数组末尾最后一项,返回移除的项
  • shift() 删除数组第一项,返回删除元素的值,如果数组为空返回undefined
  • unshift() 添加头部,改变原数组
  • sort() 数组排序,参数为一个匿名函数,如果匿名函数返回正值,则升序排列,反之相反
  • reverse() 翻转数组项的顺序 原数组改变
  • concat() 将参数添加到原数组,将参数添加到数组的末尾,并返回一个新数组,不改变原数组
  • slice() 返回原数组中指定开始下标到结束下标之间的项组成的新数组,slice接受两个参数,如果致谢一个参数,slice方法返回从该参数到数组末尾的所有项,如果有两个参数,该方法返回起始位置和结束位置之间的项,但不包括结束位置的项
  • splice() 可以实现删除,插入,替换 删除(可以删除任意属相的项,只需要指定2个参数,要删除的第一项的位置和要删除的项) 插入,替换(可以向指定位置插入任意数量的项,只需提供3个参数:起始位置,0(要删除的项),插入的项),splice()方法始终都会返回一个数组,数组中包括从原数组中删除的项,如果没有删除任何项则返回一个空数组
  • map() 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
  • some() 判断数组中是否存在满足条件的项,只要有一项满足条件,就返回true
  • every() 判断数组中每一项都是否满足条件,只有所有选项都满足条件,才会返回true
  • filter() 过滤功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组
  • forEach() 对数组进行循环遍历,对数组中的每一项运行给定函数,这个方法没有返回值,参数都是function类型,默认有传参功能,参数分别是,便利的数组内容,对应的索引,数组本身
  • indexOf() 接受两个参数,要查找的项和表示查找起点位置的索引,返回查找的项在数组的位置,没找到的情况下返回-1

伪数组转成真数组的方法

  • Array.from()
  • Array.prototype.slice.call();
  • 循环并push到新数组
  • 解构赋值:list=[..._list](es6)

window.onload与$(document).ready()的区别

  • 执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕.
  • 编写个数不同 window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个 $(document).ready()可以同时编写多个,并且都可以得到执行
  • 简化写法 window.onload没有简化写法 $(document).ready(function(){})可以简写成$(function(){});

this的理解

this代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,随着函数使用场合的不同,this的值会发生变化。但有一个总的原则就是,谁调用它,它就指向谁。一般在这几种情况下会用到它.

  • 单纯的函数调用;
  • 作为对象方法的调用;
  • 作为构造函数调用;
  • apply调用,apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象,当它的参数为空时,默认调用全局对象

跨域机制是什么,解决方式

因为同源策略的诞生,只能访问相同端口,协议,域名的网站,所以我们要进行跨域,以下是常见解决方式

  • 通过JsonP(动态创建一个script标签,通过src属性,设置一个端口号,通过接口上的某个参数向服务器传送一个函数,通过之歌回调函数接受服务器返回的数据)
  • 通过修改document.domain来跨子域
  • 使用window.name来进行跨域
  • cors
  • 反向代理
  • webSocket

get和post的区别

  • 共同点:

    • 无论是get还是post,都是可以发送数据,也可以接受数据
  • 区别:

    • get是以url方式传递数据,而post是以http请求中的body部分传递数据 ,所以说post更安全
    • get传递数据时,直接再浏览器地址栏可以看到;而post可以使用开发者工具中看到
    • get传递数据,中文不会被编码或有可能出现乱码,而post不会
    • get在IE下会走缓存,而post不会

js如何创建一个对象

对象的字面量创建 var obj= {} 创建实例对象 var obj = new Object() 构造函数的模式 function fn(){}, new fn() 工厂模式 用一个函数,通过传参数返回对象

function createObj(name,age,family) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.family = family;
    return o;
}
  • 原型模式
function Obj() {
}

Obj.prototype.name = "Obj";
Obj.prototype.age = 10;
var obj= new Obj()
  • 混合模式
function createObj(name,age) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    return o;
}

createObj.prototype.name = "Obj";
createObj.prototype.age = 10;
var _obj= new createObj()

null,undefined 的区别

  • null表示一个对象是“没有值”的值,也就是值为“空”;
  • undefined表示一个变量声明了没有初始化(赋值);
  • undefined不是一个有效的JSON,而null是;
  • undefined的类型(typeof)是undefined;null的类型(typeof)是object;
  • Javascript将未赋值的变量默认值设为undefined;Javascript不会将变量设为null。null是用来让程序员表明某个用var声明的变量时没有值的。
  • null == undefined // true null === undefined // false

对JSON 的了解

  • JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小 JSON字符串转换为JSON对象:

    • var obj =eval('('+ str +')');
    • var obj = str.parseJSON();
    • var obj = JSON.parse(str);
  • JSON对象转换为JSON字符串:

    • var last=obj.toJSONString();
    • var last=JSON.stringify(obj);

js延迟加载的方式有哪些?

defer和async、动态创建DOM方式(用得最多)、按需异步载入js

如何创建函数

  • 第一种(函数声明):function sum1(num1,num2){ return num1+num2; }
  • 第二种(函数表达式):var sum2 = function(num1,num2){ return num1+num2; }
  • 第三种(函数对象方式):var sum3 = new Function("num1","num2","return num1+num2");

三种弹窗的单词以及三种弹窗的功能

// 弹出对话框并输出一段提示信息
function ale() {
    //弹出一个对话框
    alert("提示信息!");
}

// 弹出一个询问框,有确定和取消按钮
function frim() {
    // 利用对话框返回的值 (true 或者 false)
    if (confirm("你确定提交吗?")) {
        alert("点击了确定");
    } else {
        alert("点击了取消")
    }
}

// 弹出一个输入框,输入一段文字,可以提交
function prom() {
    var name = prompt("请输入您的名字", ""); //将输入的内容赋给变量 name
    // 这里需要注意的是,prompt有两个参数,前面是提示的话,后面是当对话框出来后,在对话框里的默认值
    if (name) { // 如果返回的有内容
        alert("欢迎您:" + name)
    }
}

JavaScript的循环语句

for,for..in,while,do…while

减低页面加载时间的方法

  • 压缩css、js文件
  • 合并js、css文件,减少http请求
  • 外部js、css文件放在最底下
  • 减少dom操作,尽可能用变量替代不必要的dom操作

对象有哪些原生方法

  • Object.hasOwnProperty( ) 检查属性是否被继承
  • Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型
  • Object.propertyIsEnumerable( ) 是否可以通过for/in循环看到属性
  • Object.toLocaleString( ) 返回对象的本地字符串表示
  • Object.toString( ) 定义一个对象的字符串表示
  • Object.valueOf( ) 指定对象的原始值

JS 怎么实现一个类。怎么实例化这个类

严格来讲js中并没有类的概念,不过js中的函数可以作为构造函数来使用,通过new来实例化,其实函数本身也是一个对象。

外部JS文件出现中文字符,会出现什么问题,怎么解决

会出现乱码,加charset=”utf-8”;

target与currentTarget区别

target在事件流的目标阶段; currentTarget在事件流的捕获,目标及冒泡阶段。 只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的对象而currentTarget指向当前事件活动的对象(一般为父级)。

DOM的增删改查操作

  • 创建新节点

    • createDocumentFragment() //创建一个DOM片段
    • createElement() //创建一个具体的元素
    • createTextNode() //创建一个文本节点
  • 添加、移除、替换、插入

    • appendChild()
    • removeChild()
    • replaceChild()
    • insertBefore() //在已有的子节点前插入一个新的子节点
  • 查找

    • getElementsByTagName() //通过标签名称
    • getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
    • getElementById() //通过元素Id,唯一性
    • queryselector()//es6新增的,可选择id(#ele),class(.ele),tagName(ele)等

documen.write和 innerHTML区别

  • document.write只能重绘整个页面
  • innerHTML可以重绘页面的一部分

Ajax 解决浏览器缓存问题?

  • 在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")
  • 在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")
  • 在URL后面加上一个随机数:"fresh=" + Math.random();
  • 在URL后面加上时间戳:"nowtime=" + new Date().getTime();
  • 如果是使用jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录。

bind,call和apply的区别

  • bind方法:

    • 语法:bind(thisObj,Object1,Object2…)
    • 定义:调用一个对象的一个方法,以另一个对象替换当前对象。
    • 说明:bind方法会返回执行上下文被改变的函数而不会立即执行
  • call方法:

    • 语法:call(thisObj,Object1,Object2...)
    • 定义:调用一个对象的一个方法,以另一个对象替换当前对象。
    • 说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
  • apply方法:

    • 语法:apply(thisObj,[argArray])
    • 定义:应用某一对象的一个方法,用另一个对象替换当前对象。
    • 说明:如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

javascript的本地对象,内置对象和宿主对象

  • 本地对象为array obj regexp等可以new实例化
  • 内置对象为gload Math 等不可以实例化的
  • 宿主为浏览器自带的document,window 等

列举浏览器对象模型BOM里常用的对象,并列举window对象的常用方法

  • 对象:window, document, location, screen, history, navigator
  • 方法:alert(), confirm(), prompt(), open(), close()

iframe的优缺点

  • 优点:

    • 解决加载缓慢的第三方内容如图标和广告等的加载问题
    • Security sandbox
    • 并行加载脚本
  • 缺点:

    • iframe会阻塞主页面的Onload事件
    • 即时内容为空,加载也需要时间
    • 没有语意

Cookie的弊端

  • Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
  • 安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
  • 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。

谈谈js精度问题

由于计算机是用二进制来存储和处理数字,不能精确表示浮点数,而JavaScript是一种弱类型的脚本语言,没有相应的封装类来处理浮点数运算,直接计算会导致运算精度丢失,c#的decimal和Java的BigDecimal之所以没有出现精度差异,只是因为在其内部作了相应处理,把这种精度差异给屏蔽掉了,而javascript是一种弱类型的脚本语言,本身并没有对计算精度做相应的处理,这就需要我们另外想办法处理了。所以0.1+0.2!==0.3。 为了避免产生精度差异,把需要计算的数字升级(乘以10的n次幂)成计算机能够精确识别的整数,等计算完毕再降级(除以10的n次幂),这是大部分编程语言处理精度差异的通用方法。

js哪些值会强制转换为false

在条件判断时,除了 undefined, null, false, NaN, '', 0, -0,其他所 有值都转为 true,包括所有对象。

link添加预加载预渲染

  • 预加载:强制浏览器请求资源,并且不会阻塞 onload 事件, 可以使用以下代码开启预加载
  • 预渲染: 可以通过预渲染将下载的文件预先在后台渲染,可以使用以下代码开启预渲染

JS事件的offsetX、offsetY、clientX、clientY、pageX、pageY、screenX、screenY的区别

  • offsetX、offsetY: 鼠标相对于事件源元素(srcElement)的X,Y坐标
  • clientX、clientY: 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。
  • pageX、pagey: 类似于event.clientX、event.clientY,但它们使用的是文档坐标而非窗口坐标。这2个属性不是标准属性,但得到了广泛支持,IE事件中没有这2个属性
  • screenX、screenY: 鼠标相对于用户显示器屏幕左上角的X,Y坐标。
贡献者: mankueng