-
Js中使用typeof能得到的类型
typeof underfined //underfined typeof 'abc' //string typeof 123 //number typeof true //boolean typeof {} //object typeof [] //object typeof null //object typeof console.log //function
-
何时使用 === 和 ==
if (obj.a == null) { //判定对象obj的a属性是否存在 //这里相当于 obj.a === null || obj.a === underfined ,的简写形式。 //这是jQuery源码中的推荐写法。除此之外其他时候都使用 ===。 }
-
Js中的内置函数
Boolean / Number / String / Object / Array / Function / Date / RegExp / Error
-
Js中按存储方式区分变量类型
值类型 引用类型 var a = 100; var obj1 = {num:10}; var b = a; var obj2 = obj1; a = 111; obj1.num = 22; console.log (b); //100 console.log (obj2.num); //22 //把数值作为一个整块存入内存中, //只是对对象的一个引用,把指针 //随后每个值会变得独立。 //指向对象,多个变量共用一个值。
-
如何理解JSON
JSON.stringify ({a:10, b:20})
——把JSON输出成字符串
JSON.parse('{"a": 10, "b": 20}')
——把该字符串转化成JSON
根据以上可知,JSON 就是一个JS对象。
但同时,JSON也是一种数据格式。
-
如何准确判断一个变量是数组类型
var arr = []; arr instanceof Array; //true,通过识别arr的构造函数来判断。 typeof arr //Object,typeof 并不能识别引用类型的详细类型。
-
写一个原型链继承的例子
一个封装DOM查询的栗子(获取一个DOM内容然后导入到事件)
div1的每一次链式操作都是一次继承,div1本身并没有 html 和 on的属性,但是它继承了它的构造函数Elem的显式原型的属性。//创建构造函数 function Elem (id) { this.elem = 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 (' id1 '); div1.html('<p>链式1</p>').on ('click', function () { console.log('链式2'); }).html ('链式3');
-
描述new一个对象的过程
function Foo (name, age) { this.name = name; this.age = age; this.class = 'class-1'; return this; } var f1 = new Foo ('XX', 18); var f2 = new Foo ('BB', 18);
- 创建一个新对象。
- this 指向这个新对象。
- 给 this 赋值(添加属性)。
- return this ,完成构造。
-
zepto(或其他框架)源码中如何使用原型链
语法跟 jQuery 相似
更加轻量化,砍了一些 api
读过一些源码,关于原型链和闭包。
-
说一下对变量提升的理解
其实就是执行上下文的概念。
浅显的可以理解成,
变量定义和函数声明在作用域内被提前执行。
在函数作用域内还包括 this 和 arguments。console.log (a); //undefined var a = 100; fn ('AAA'); // 'AAA' 20 function fn(name) { age = 20; console.log (name, 20); var age; }
-
说明this的几种不同使用场景
①作为构造函数执行
②作为对象属性执行
③作为普通函数执行
④call apply bind方法var a = { name: 'AAA'; fn: function () { console.log (this.name); // 就是这个this }; }; //作为对象属性执行 a.fn(); // AAA //call apply bind方法 a.fn.call ({name:"BBB"}); // BBB //作为普通函数执行 var fn1 = a.fn(); fn1(); // window 这个函数就是由window来运行的。
-
创建10个 <a>,点击弹出各自对应的序号
为每一个 a 标签构造一个函数作用域,var i; for ( i = 0; i < 10; i++ ) { ( function ( i ) { var a = document.createElement('a'); a.innerHTML = i + "<br/>"; a.addEventListener ('click', function (e) { e.preventDefault (); alert ( i ); }); document.body.appendChild (a); }) ( i ); }
这样在for循环的时候,变化的 i 就不会影响到每一个作用域里的 i 。
-
如何理解作用域
回答要点:①自由变量 ②作用域链,即自由变量的查找 ③闭包的两个场景
作用域可以理解为代码执行的一个区域(环境),
每个作用域中的变量是相对独立的,可以分别定义同一个变量而不冲突。
但如果作用域中,没有定义某个变量,是可以到父作用域中去寻找的。
但父作用域中没有的变量,不能去子作用域中寻找,这就是作用域链。
除非使用闭包,才能从外获取作用域内的变量。
-
实际开发中的闭包应用
function isFirstLoad () { var _list = []; // 创建一个数组来装id return function (id) { if ( _list.indexOf(id) >= 0 ) { //用indexOf[id]来判断id在数组中的序号 console.log(false); return false; // 如果有序号,即已经存在,终止函数。 }; _list.push(id); // 若不存在则加入到数组中。 console.log(true); }; }; var isFirst = isFirstLoad(); //运行isFirstLoad()返回一个闭包赋到isFirst中。 isFirst (10); //true isFirst (10); //false isFirst (20); //true isFirst (20); //false
-
同步和异步的区别,各举一个例子
- 同步会阻塞代码执行,而异步不会。
- alert是同步,阻塞代码,alert之后的代码停止执行,知道确定alert。
setTimeout是异步,不阻塞,继续执行后面的代码,再执行setTimeout的内容。
-
关于 setTimeout 的笔试题
运行的结果是 1、3、5、2、4。console.log(1); setTimeout (function () { console.log(2); }, 0); console.log(3); setTimeout (function () { console.log(4); }, 1000); console.log(5);
即使setTimeout的事件为0,函数也被会挂起,等到最后再回头执行,
但是因为其时间短,所以在挂起的队列里排前面。
-
前端使用异步的场景有哪些
因为js是单线程,所以需要异步,避免阻塞。-
定时任务:setTimeout,setInterval
-
网络请求:ajax 请求,动态 <img> 加载
-
事件绑定。
-
-
获取 2017 - 01 - 12 格式的日期
此 demo,在 getDate 函数中,function getDate (da) { if ( !da ) { da = new Date(); }; var year = da.getFullYear(); var month = da.getMonth() + 1; var day = da.getDate(); if ( month < 10 ) { month = "0" + month; }; if ( day < 10 ) { day = "0" + day; }; return year + "-" + month + "-" + day; } var da = new Date(); var date = getDate(da); console.log(date);
第一块代码,if 是为了避免传入的 da 出错,重新获取。
第二块代码为获取年月日,月份要+1。
第三块代码是修复数字为一位数时不好看的情况。
第四块代码为返回结果。
其中第三四块中,都用了强制类型转化,通过与字符串拼接,把数字转化为字符串。
-
获取随机数,转化为长度一致的字符串格式
var random = Math.random(); var random = random + '0000000000'; // 强制类型转换,并补长随机数。 var random = random.slice(0, 10); // 截取前十位,截多少上面就补多少。 console.log(random);
-
写一个能遍历对象和数组的通用 forEach 函数
- function allEach (object, fn) { // 构建万能遍历,传入object和方法。
- var key;
- if (object instanceof Array) { // 判定是否数组
- object.forEach ( function (item, index) {
+ fn (index, item);
// 在数组上使用forEach,用function接收item和index,然后在传给fn
- });
- } else { // 不是数组的话那就是对象
- for (key in object) { // key是对象里的成员
- if (object.hasOwnProperty (key)) { // 判定key是否为对象的原生属性
+ fn (key, object[key]); // 把该属性和属性的值传给 fn
- };
- };
- };
- };
+
- var arr = [2, 4, 5]; // 定义一个数组
- allEach (arr, function (index, item) { // 使用allEach方法,传入数组和要使用的方法
- console.log (index, item);
- });
+ var obj = {X:100, Y:200};
- allEach (obj, function (key, value) {
- console.log (key, value);
- });
-
DOM 是哪种基本数据结构
树
-
DOM 操作的常用 API 有哪些
针对节点:获取 DOM节点、获取DOM节点的 property 和 Attribute 等
针对树结构:获取元素父节点、获取元素子节点等
新增节点和删除节点
-
DOM 节点的 Attribute 和 property 有什么区别
- property:Js 对象的属性,获取和修改都是针对这个对象的。
- Attribute:html 标签的属性,获取和修改都是针对这个标签的。
-
如何检测浏览器的类型
navigator.userAgen - 返回一个字符串
通过字符串的内容,可以判断出浏览器类型和一些基本特性。
但也一定完全准确,有可能会被修改。
-
拆解 url 的各部分
以 http://primerscern.xyz/demo-blog-site?99#mid=100 为例console.log(location.href) // http://primerscern.xyz/demo-blog-site?99#mid=100 console.log(location.protocaol) // http: console.log(location.host) // primerscern.xyz console.log(location.pathname) // /demo-blog-site/ console.log(location.search) // ?99 console.log(location.hash) // #mid=100 // 通过每一个属性,可以获取,也可以修改。
-
简述事件冒泡流程
-
DOM树形结构
冒泡的顺序,根据DOM树形结构,按小到大(内到外、子到父)冒。 -
事件冒泡
逐层冒,逐层触发事件。 -
阻止冒泡
有需要时,可以再某层阻止冒泡,来停止继续向上冒泡。 -
冒泡应用
多数应用在事件委托。
-
DOM树形结构
-
什么时候用到事件委托,优点是什么
当需要大量绑定事件时,就会用到事件代理。
好处就是
① 代码比较简洁,绑定一次代替多次。
② 浏览器压力较小。
③ 可以实现动态绑定。
-
编写一个通用的事件监听绑定
function bindEvent (ele, type, selector, fn) { // 加入选择器应对更多情况 if (fn == null) { fn = selector selector = null }//当不使用selector时,把fn换到前面来 ele.addEventListener(type, function (e) { //绑定事件,绑定时执行判断 var target if (selector) { //需要代理 target = e.target if (target.matches(selector)) { //判断,是否匹配选择器 fn.call (target, e) } //执行主体为e.target,所以要把函数给回它执行 } else { //不代理 fn(e) } }) }
-
编写一个原生的 ajzx
- var xhr = new XMLHttpRequest()
- xhr.open("GET", "/api", false)
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
+ if (xhr..status == 200) {
- alert(xhr.responseText)
- }
- }
- }
+ xhr.send(null)
-
跨域的几种实现方式
- 三个标签:<img src=''><script src='' <link href=''>。
- JSONP
-
服务器设置 http header
-
描述 cookie、sessionStorage 和 localStorage 的区别
- 容量:cookie 只有4kb ,而 Storage 则有 5m
- ajax:每次都会携带 cookie,占用性能,Storage 则不带,仅用于存储。
-
API 易用性:cookie 使用需要自行封装一些方法,而 Storage 不用。
document.cookie
,localStorage.setItem(key, value)
,localStorage.getItem(key)
-
从输入 url 到得到 html 的详细过程
- 浏览器把输入的 url 发送到 DNS 服务器,然后返回该域名的 IP 地址
- 向这个 IP 的机器(服务器)发送 http 请求
- 服务器收到、处理并返回 http 请求
- 浏览器得到返回的内容,然后继续执行。
-
window.onload 和 DOMContentLoaded 的区别
前者是页面的资源全部加载完毕,包括图片,视频等。
后者是当 DOM 渲染完即可,不需要等待图片视频加载。
-
浏览器渲染页面的过程
- 根据 HTML 结构生成 DOM Tree(文档树形结构)
- 根据 CSS 生成 CSSOM(与DOM对应)
- 将 DOM 和 CSSOM 整合形成 RenderTree
- 根据 RenderTree 开始渲染和展示
- 遇到 <script> 时,会执行并且会阻塞渲染
***
***
Wait me back