js基础

1.document load 和 document ready 的区别

页面加载完成有两种事件

1.load是当页面所有资源全部加载完成后(包括DOM文档树,css文件,js文件,图片资源等),执行一个函数

问题:如果图片资源较多,加载时间较长,onload后等待执行的函数需要等待较长时间,所以一些效果可能受到影响

2.$(document).ready()是当DOM文档树加载完成后执行一个函数 (不包含图片,css等)所以会比load较快执行

在原生的jS中不包括ready()这个方法,只有load方法就是onload事件

时倾 13:53:23

2. JavaScript 中如何检测一个变量是一个 String 类型?

三种方法(typeof、constructor、Object.prototype.toString.call())解析:①typeof

typeof('123') === "string" // true

typeof '123' === "string" // true

②constructor

'123'.constructor === String // true

③Object.prototype.toString.call()

Object.prototype.toString.call('123') === '[object String]' // true2. JavaScript 中如何检测一个变量是一个 String 类型?

三种方法(typeof、constructor、Object.prototype.toString.call())解析:①typeof

typeof('123') === "string" // true

typeof '123' === "string" // true

②constructor

'123'.constructor === String // true

③Object.prototype.toString.call()

Object.prototype.toString.call('123') === '[object String]' // true

3.请用 js 去除字符串空格?

replace 正则匹配方法、str.trim()方法、JQ 方法:$.trim(str)方法解析:方法一:replace 正则匹配方法去除字符串内所有的空格:str = str.replace(/\s*/g,"");去除字符串内两头的空格:str = str.replace(/^\s*|\s*$/g,"");去除字符串内左侧的空格:str = str.replace(/^\s*/,"");去除字符串内右侧的空格:str = str.replace(/(\s*$)/g,"");示例:var str = " 6 6 ";

var str_1 = str.replace(/\s*/g, "");

console.log(str_1); //66

var str = " 6 6 ";

var str_1 = str.replace(/^\s*|\s*$/g, "");

console.log(str_1); //6 6//输出左右侧均无空格

var str = " 6 6 ";

var str_1 = str.replace(/^\s*/, "");

console.log(str_1); //6 6 //输出右侧有空格左侧无空格

var str = " 6 6 ";

var str_1 = str.replace(/(\s*$)/g, "");

console.log(str_1); // 6 6//输出左侧有空格右侧无空格方法二:str.trim()方法trim()方法是用来删除字符串两端的空白字符并返回,trim 方法并不影响原来的字符串本身,它返回的是一个新的字符串。缺陷:只能去除字符串两端的空格,不能去除中间的空格示例:var str = " 6 6 ";

var str_1 = str.trim();

console.log(str_1); //6 6//输出左右侧均无空格方法三:JQ 方法:$.trim(str)方法$.trim() 函数用于去除字符串两端的空白字符。注意:$.trim()函数会移除字符串开始和末尾处的所有换行符,空格(包括连续的空格)和制表符。如果这些空白字符在字符串中间时,它们将被保留,不会被移除。示例:var str = " 6 6 ";

var str_1 = $.trim(str);

console.log(str_1); //6 6//输出左右侧均无空格3.请用 js 去除字符串空格?

replace 正则匹配方法、str.trim()方法、JQ 方法:$.trim(str)方法解析:方法一:replace 正则匹配方法去除字符串内所有的空格:str = str.replace(/\s*/g,"");去除字符串内两头的空格:str = str.replace(/^\s*|\s*$/g,"");去除字符串内左侧的空格:str = str.replace(/^\s*/,"");去除字符串内右侧的空格:str = str.replace(/(\s*$)/g,"");示例:var str = " 6 6 ";

var str_1 = str.replace(/\s*/g, "");

console.log(str_1); //66

var str = " 6 6 ";

var str_1 = str.replace(/^\s*|\s*$/g, "");

console.log(str_1); //6 6//输出左右侧均无空格

var str = " 6 6 ";

var str_1 = str.replace(/^\s*/, "");

console.log(str_1); //6 6 //输出右侧有空格左侧无空格

var str = " 6 6 ";

var str_1 = str.replace(/(\s*$)/g, "");

console.log(str_1); // 6 6//输出左侧有空格右侧无空格方法二:str.trim()方法trim()方法是用来删除字符串两端的空白字符并返回,trim 方法并不影响原来的字符串本身,它返回的是一个新的字符串。缺陷:只能去除字符串两端的空格,不能去除中间的空格示例:var str = " 6 6 ";

var str_1 = str.trim();

console.log(str_1); //6 6//输出左右侧均无空格方法三:JQ 方法:$.trim(str)方法$.trim() 函数用于去除字符串两端的空白字符。注意:$.trim()函数会移除字符串开始和末尾处的所有换行符,空格(包括连续的空格)和制表符。如果这些空白字符在字符串中间时,它们将被保留,不会被移除。示例:var str = " 6 6 ";

var str_1 = $.trim(str);

console.log(str_1); //6 6//输出左右侧均无空格

4.js 是一门怎样的语言,它有什么特点

1.脚本语言。JavaScript 是一种解释型的脚本语言,C、C++等语言先编译后执行,而 JavaScript 是在程序的运行过程中逐行进行解释。2.基于对象。JavaScript 是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。3.简单。JavaScript 语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于 Java 基本语句和控制的脚本语言,其设计简单紧凑。4.动态性。JavaScript 是一种采用事件驱动的脚本语言,它不需要经过 Web 服务器就可以对用户的输入做出响应。5.跨平台性。JavaScript 脚本语言不依赖于操作系统,仅需要浏览器的支持。4.js 是一门怎样的语言,它有什么特点

1.脚本语言。JavaScript 是一种解释型的脚本语言,C、C++等语言先编译后执行,而 JavaScript 是在程序的运行过程中逐行进行解释。2.基于对象。JavaScript 是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。3.简单。JavaScript 语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于 Java 基本语句和控制的脚本语言,其设计简单紧凑。4.动态性。JavaScript 是一种采用事件驱动的脚本语言,它不需要经过 Web 服务器就可以对用户的输入做出响应。5.跨平台性。JavaScript 脚本语言不依赖于操作系统,仅需要浏览器的支持。

5.== 和 === 的不同

==是抽象相等运算符,而===是严格相等运算符。==运算符是在进行必要的类型转换后,再比较。===运算符不会进行类型转换,所以如果两个值不是相同的类型,会直接返回false。使用==时,可能发生一些特别的事情,例如:1 == "1"; // true

1 == [1]; // true

1 == true; // true

0 == ""; // true

0 == "0"; // true

0 == false; // true如果你对==和===的概念不是特别了解,建议大多数情况下使用===5.== 和 === 的不同

==是抽象相等运算符,而===是严格相等运算符。==运算符是在进行必要的类型转换后,再比较。===运算符不会进行类型转换,所以如果两个值不是相同的类型,会直接返回false。使用==时,可能发生一些特别的事情,例如:1 == "1"; // true

1 == [1]; // true

1 == true; // true

0 == ""; // true

0 == "0"; // true

0 == false; // true如果你对==和===的概念不是特别了解,建议大多数情况下使用==

6.怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点

createDocumentFragment() //创建一个 DOM 片段

createElement() //创建一个具体的元素

createTextNode() //创建一个文本节点

2)添加、移除、替换、插入

appendChild() //添加

removeChild() //移除

replaceChild() //替换

insertBefore() //插入

3)查找

getElementsByTagName() //通过标签名称

getElementsByName() //通过元素的 Name 属性的值

getElementById() //通过元素 Id,唯一性

6.怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点

createDocumentFragment() //创建一个 DOM 片段

createElement() //创建一个具体的元素

createTextNode() //创建一个文本节点

2)添加、移除、替换、插入

appendChild() //添加

removeChild() //移除

replaceChild() //替换

insertBefore() //插入

3)查找

getElementsByTagName() //通过标签名称

getElementsByName() //通过元素的 Name 属性的值

getElementById() //通过元素 Id,唯一性

7.事件委托是什么

利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!解析:1、那什么样的事件可以用事件委托,什么样的事件不可以用呢?

适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

值得注意的是,mouseover 和 mouseout 虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。

不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说 focus,blur 之类的,本身就没用冒泡的特性,自然就不用事件委托了。

2、为什么要用事件委托

1.提高性能

‹ul›

‹li›苹果‹/li›

‹li›香蕉‹/li›

‹li›凤梨‹/li›

‹/ul›

// good

document.querySelector('ul').onclick = (event) =› {

let target = event.target

if (target.nodeName === 'LI') {

console.log(target.innerHTML)

}

}

// bad

document.querySelectorAll('li').forEach((e) =› {

e.onclick = function() {

console.log(this.innerHTML)

}

})

2.新添加的元素还会有之前的事件。

3、事件冒泡与事件委托的对比

事件冒泡:box 内部无论是什么元素,点击后都会触发 box 的点击事件

事件委托:可以对 box 内部的元素进行筛选

4、事件委托怎么取索引?    ‹ul id="ul"›

‹li›aaaaaaaa‹/li›

‹li›事件委托了 点击当前,如何获取 这个点击的下标‹/li›

‹li›cccccccc‹/li›

‹/ul›

‹script›

window.onload = function () {

var oUl = document.getElementById("ul");

var aLi = oUl.getElementsByTagName("li");

oUl.onclick = function (ev) {

var ev = ev || window.event;

var target = ev.target || ev.srcElement;

if (target.nodeName.toLowerCase() == "li") {

var that = target;

var index;

for (var i = 0; i ‹ aLi.length; i++)

if (aLi[i] === target) index = i;

if (index ›= 0) alert('我的下标是第' + index + '个');

target.style.background = "red";

}

}

}

‹/script›拓展:

键盘事件:keydown keypress keyup

鼠标事件:mousedown mouseup mousemove mouseout mouseover

参考7.事件委托是什么

利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!解析:1、那什么样的事件可以用事件委托,什么样的事件不可以用呢?

适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

值得注意的是,mouseover 和 mouseout 虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。

不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说 focus,blur 之类的,本身就没用冒泡的特性,自然就不用事件委托了。

2、为什么要用事件委托

1.提高性能

‹ul›

‹li›苹果‹/li›

‹li›香蕉‹/li›

‹li›凤梨‹/li›

‹/ul›

// good

document.querySelector('ul').onclick = (event) =› {

let target = event.target

if (target.nodeName === 'LI') {

console.log(target.innerHTML)

}

}

// bad

document.querySelectorAll('li').forEach((e) =› {

e.onclick = function() {

console.log(this.innerHTML)

}

})

2.新添加的元素还会有之前的事件。

3、事件冒泡与事件委托的对比

事件冒泡:box 内部无论是什么元素,点击后都会触发 box 的点击事件

事件委托:可以对 box 内部的元素进行筛选

4、事件委托怎么取索引?    ‹ul id="ul"›

‹li›aaaaaaaa‹/li›

‹li›事件委托了 点击当前,如何获取 这个点击的下标‹/li›

‹li›cccccccc‹/li›

‹/ul›

‹script›

window.onload = function () {

var oUl = document.getElementById("ul");

var aLi = oUl.getElementsByTagName("li");

oUl.onclick = function (ev) {

var ev = ev || window.event;

var target = ev.target || ev.srcElement;

if (target.nodeName.toLowerCase() == "li") {

var that = target;

var index;

for (var i = 0; i ‹ aLi.length; i++)

if (aLi[i] === target) index = i;

if (index ›= 0) alert('我的下标是第' + index + '个');

target.style.background = "red";

}

}

}

‹/script›拓展:

键盘事件:keydown keypress keyup

鼠标事件:mousedown mouseup mousemove mouseout mouseover

8.require 与 import 的区别

两者的加载方式不同、规范不同第一、两者的加载方式不同,require 是在运行时加载,而 import 是在编译时加载require('./a')(); // a 模块是一个函数,立即执行 a 模块函数var data = require('./a').data; // a 模块导出的是一个对象var a = require('./a')[0]; // a 模块导出的是一个数组 ======› 哪都行import $ from 'jquery';import * as _ from '_';import {a,b,c} from './a';import {default as alias, a as a_a, b, c} from './a'; ======›用在开头第二、规范不同,require 是 CommonJS/AMD 规范,import 是 ESMAScript6+规范第三、require 特点:社区方案,提供了服务器/浏览器的模块加载方案。非语言层面的标准。只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。import 特点:语言规格层面支持模块功能。支持编译时静态分析,便于 JS 引入宏和类型检验。动态绑定。8.require 与 import 的区别

两者的加载方式不同、规范不同第一、两者的加载方式不同,require 是在运行时加载,而 import 是在编译时加载require('./a')(); // a 模块是一个函数,立即执行 a 模块函数var data = require('./a').data; // a 模块导出的是一个对象var a = require('./a')[0]; // a 模块导出的是一个数组 ======› 哪都行import $ from 'jquery';import * as _ from '_';import {a,b,c} from './a';import {default as alias, a as a_a, b, c} from './a'; ======›用在开头第二、规范不同,require 是 CommonJS/AMD 规范,import 是 ESMAScript6+规范第三、require 特点:社区方案,提供了服务器/浏览器的模块加载方案。非语言层面的标准。只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。import 特点:语言规格层面支持模块功能。支持编译时静态分析,便于 JS 引入宏和类型检验。动态绑定。

9.javascript 对象的几种创建方式

第一种:Object 构造函数创建var Person = new Object();

Person.name = "Nike";

Person.age = 29;这行代码创建了 Object 引用类型的一个新实例,然后把实例保存在变量 Person 中。第二种:使用对象字面量表示法var Person = {}; //相当于 var Person = new Object();

var Person = {

name: 'Nike';

age: 29;

}对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。也就是说,第一种和第二种方式创建对象的方法其实都是一样的,只是写法上的区别不同在介绍第三种的创建方法之前,我们应该要明白为什么还要用别的方法来创建对象,也就是第一种,第二种方法的缺点所在:它们都是用了同一个接口创建很多对象,会产生大量的重复代码,就是如果你有 100 个对象,那你要输入 100 次很多相同的代码。那我们有什么方法来避免过多的重复代码呢,就是把创建对象的过程封装在函数体内,通过函数的调用直接生成对象。第三种:使用工厂模式创建对象function createPerson(name, age, job) {

var o = new Object();

o.name = name;

o.age = age;

o.job = job;

o.sayName = function() {

alert(

this.name);

};

return o;

}

var person1 = createPerson("Nike", 29, "teacher");

var person2 = createPerson("Arvin", 20, "student");在使用工厂模式创建对象的时候,我们都可以注意到,在 createPerson 函数中,返回的是一个对象。那么我们就无法判断返回的对象究竟是一个什么样的类型。于是就出现了第四种创建对象的模式。第四种:使用构造函数创建对象function Person(name, age, job) {

this.name = name;

this.age = age;

this.job = job;

this.sayName = function() {

alert(

this.name);

};

}

var person1 = new Person("Nike", 29, "teacher");

var person2 = new Person("Arvin", 20, "student");对比工厂模式,我们可以发现以下区别:1.没有显示地创建对象2.直接将属性和方法赋给了 this 对象3.没有 return 语句4.终于可以识别的对象的类型。对于检测对象类型,我们应该使用 instanceof 操作符,我们来进行自主检测:alert(person1 instanceof Object); //ture

alert(person1 instanceof Person); //ture

alert(person2 instanceof Object); //ture

alert(person2 instanceof Object); //ture同时我们也应该明白,按照惯例,构造函数始终要应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。那么构造函数确实挺好用的,但是它也有它的缺点:就是每个方法都要在每个实例上重新创建一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要的内存。于是出现了第五种创建对象的方法第五种:原型创建对象模式function Person() {}

Person.prototype.name = "Nike";

Person.prototype.age = 20;

Person.prototype.jbo = "teacher";

Person.prototype.sayName = function() {

alert(

this.name);

};

var person1 = new Person();

person1.sayName();使用原型创建对象的方式,可以让所有对象实例共享它所包含的属性和方法。如果是使用原型创建对象模式,请看下面代码:function Person() {}

Person.prototype.name = "Nike";

Person.prototype.age = 20;

Person.prototype.jbo = "teacher";

Person.prototype.sayName = function() {

alert(

this.name);

};

var person1 = new Person();

var person2 = new Person();

person1.name = "Greg";

alert(

person1.name); //'Greg' --来自实例

alert(

person2.name); //'Nike' --来自原型当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性。这时候我们就可以使用构造函数模式与原型模式结合的方式,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性第六种:组合使用构造函数模式和原型模式function Person(name, age, job) {

this.name = name;

this.age = age;

this.job = job;

}

Person.prototype = {

constructor: Person,

sayName: function() {

alert(

this.name);

};

}

var person1 = new Person('Nike', 20, 'teacher');解析:

参考9.javascript 对象的几种创建方式

第一种:Object 构造函数创建var Person = new Object();

Person.name = "Nike";

Person.age = 29;这行代码创建了 Object 引用类型的一个新实例,然后把实例保存在变量 Person 中。第二种:使用对象字面量表示法var Person = {}; //相当于 var Person = new Object();

var Person = {

name: 'Nike';

age: 29;

}对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。也就是说,第一种和第二种方式创建对象的方法其实都是一样的,只是写法上的区别不同在介绍第三种的创建方法之前,我们应该要明白为什么还要用别的方法来创建对象,也就是第一种,第二种方法的缺点所在:它们都是用了同一个接口创建很多对象,会产生大量的重复代码,就是如果你有 100 个对象,那你要输入 100 次很多相同的代码。那我们有什么方法来避免过多的重复代码呢,就是把创建对象的过程封装在函数体内,通过函数的调用直接生成对象。第三种:使用工厂模式创建对象function createPerson(name, age, job) {

var o = new Object();

o.name = name;

o.age = age;

o.job = job;

o.sayName = function() {

alert(

this.name);

};

return o;

}

var person1 = createPerson("Nike", 29, "teacher");

var person2 = createPerson("Arvin", 20, "student");在使用工厂模式创建对象的时候,我们都可以注意到,在 createPerson 函数中,返回的是一个对象。那么我们就无法判断返回的对象究竟是一个什么样的类型。于是就出现了第四种创建对象的模式。第四种:使用构造函数创建对象function Person(name, age, job) {

this.name = name;

this.age = age;

this.job = job;

this.sayName = function() {

alert(

this.name);

};

}

var person1 = new Person("Nike", 29, "teacher");

var person2 = new Person("Arvin", 20, "student");对比工厂模式,我们可以发现以下区别:1.没有显示地创建对象2.直接将属性和方法赋给了 this 对象3.没有 return 语句4.终于可以识别的对象的类型。对于检测对象类型,我们应该使用 instanceof 操作符,我们来进行自主检测:alert(person1 instanceof Object); //ture

alert(person1 instanceof Person); //ture

alert(person2 instanceof Object); //ture

alert(person2 instanceof Object); //ture同时我们也应该明白,按照惯例,构造函数始终要应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。那么构造函数确实挺好用的,但是它也有它的缺点:就是每个方法都要在每个实例上重新创建一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要的内存。于是出现了第五种创建对象的方法第五种:原型创建对象模式function Person() {}

Person.prototype.name = "Nike";

Person.prototype.age = 20;

Person.prototype.jbo = "teacher";

Person.prototype.sayName = function() {

alert(

this.name);

};

var person1 = new Person();

person1.sayName();使用原型创建对象的方式,可以让所有对象实例共享它所包含的属性和方法。如果是使用原型创建对象模式,请看下面代码:function Person() {}

Person.prototype.name = "Nike";

10.JavaScript 继承的方式和优缺点

六种方式

一、原型链继承

缺点:

1.引用类型的属性被所有实例共享

2.在创建 Child 的实例时,不能向 Parent 传参

二、借用构造函数(经典继承)

优点:

1.避免了引用类型的属性被所有实例共享

2.可以在 Child 中向 Parent 传参

缺点:

1.方法都在构造函数中定义,每次创建实例都会创建一遍方法。

三、组合继承

优点:

1.融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。

四、原型式继承

缺点:

1.包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样。

五、寄生式继承

缺点:

1.跟借用构造函数模式一样,每次创建对象都会创建一遍方法。

六、寄生组合式继承

优点:

1.这种方式的高效率体现它只调用了一次 Parent 构造函数,并且因此避免了在 Parent.prototype 上面创建不必要的、多余的属性。

2.与此同时,原型链还能保持不变;

3.因此,还能够正常使用 instanceof 和 isPrototypeOf。

开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式

解析:参考10.JavaScript 继承的方式和优缺点

六种方式

一、原型链继承

缺点:

1.引用类型的属性被所有实例共享

2.在创建 Child 的实例时,不能向 Parent 传参

二、借用构造函数(经典继承)

优点:

1.避免了引用类型的属性被所有实例共享

2.可以在 Child 中向 Parent 传参

缺点:

1.方法都在构造函数中定义,每次创建实例都会创建一遍方法。

三、组合继承

优点:

1.融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。

四、原型式继承

缺点:

1.包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样。

五、寄生式继承

缺点:

1.跟借用构造函数模式一样,每次创建对象都会创建一遍方法。

六、寄生组合式继承

优点:

1.这种方式的高效率体现它只调用了一次 Parent 构造函数,并且因此避免了在 Parent.prototype 上面创建不必要的、多余的属性。

2.与此同时,原型链还能保持不变;

3.因此,还能够正常使用 instanceof 和 isPrototypeOf。

开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式

解析:参考

11.什么是原型链?

通过一个对象的proto可以找到它的原型对象,原型对象也是一个对象,就可以通过原型对象的proto,最后找到了我们的 Object.prototype,从实例的原型对象开始一直到 Object.prototype 就是我们的原型链解析:11.什么是原型链?

通过一个对象的proto可以找到它的原型对象,原型对象也是一个对象,就可以通过原型对象的proto,最后找到了我们的 Object.prototype,从实例的原型对象开始一直到 Object.prototype 就是我们的原型链解析:

12.复杂数据类型如何转变为字符串

首先,会调用 valueOf 方法,如果方法的返回值是一个基本数据类型,就返回这个值,

如果调用 valueOf 方法之后的返回值仍旧是一个复杂数据类型,就会调用该对象的 toString 方法,

如果 toString 方法调用之后的返回值是一个基本数据类型,就返回这个值,

如果 toString 方法调用之后的返回值是一个复杂数据类型,就报一个错误。

解析:1;

var obj = {

valueOf: function() {

return 1;

}

};

console.log(obj + ""); //'1'

2;

var obj = {

valueOf: function() {

return [1, 2];

}

};

console.log(obj + ""); //'[object Object]';

3;

var obj = {

valueOf: function() {

return [1, 2];

},

toString: function() {

return 1;

}

};

console.log(obj + ""); //'1';

4;

var obj = {

valueOf: function() {

return [1, 2];

},

toString: function() {

return [1, 2, 3];

}

};

console.log(obj + ""); // 报错 Uncaught TypeError: Cannot convert object to primitive value拓展:var arr = [new Object(), new Date(), new RegExp(), new String(), new Number(), new Boolean(), new Function(), new Array(), Math] console.log(arr.length) // 9

for (var i = 0; i ‹ arr.length; i++) {

arr[i].valueOf = function() {

return [1, 2, 3]

}

arr[i].toString = function() {

return 'toString'

}

console.log(arr[i] + '')

}1、若 return [1,2,3]处为 return "valueof",得到的返回值是 valueof toString 7valueof

说明:其他八种复杂数据类型是先调用 valueOf 方法,时间对象是先调用 toString 方法2、改成 return [1,2,3],得到的返回值是 9toString

说明:执行 valueof 后都来执行 toString12.复杂数据类型如何转变为字符串

首先,会调用 valueOf 方法,如果方法的返回值是一个基本数据类型,就返回这个值,

如果调用 valueOf 方法之后的返回值仍旧是一个复杂数据类型,就会调用该对象的 toString 方法,

如果 toString 方法调用之后的返回值是一个基本数据类型,就返回这个值,

如果 toString 方法调用之后的返回值是一个复杂数据类型,就报一个错误。

解析:1;

var obj = {

valueOf: function() {

return 1;

}

};

console.log(obj + ""); //'1'

2;

var obj = {

valueOf: function() {

return [1, 2];

}

};

console.log(obj + ""); //'[object Object]';

3;

var obj = {

valueOf: function() {

return [1, 2];

},

toString: function() {

return 1;

}

};

console.log(obj + ""); //'1';

4;

var obj = {

valueOf: function() {

return [1, 2];

},

toString: function() {

return [1, 2, 3];

}

};

console.log(obj + ""); // 报错 Uncaught TypeError: Cannot convert object to primitive value拓展:var arr = [new Object(), new Date(), new RegExp(), new String(), new Number(), new Boolean(), new Function(), new Array(), Math] console.log(arr.length) // 9

for (var i = 0; i ‹ arr.length; i++) {

arr[i].valueOf = function() {

return [1, 2, 3]

}

arr[i].toString = function() {

return 'toString'

}

console.log(arr[i] + '')

}1、若 return [1,2,3]处为 return "valueof",得到的返回值是 valueof toString 7valueof

说明:其他八种复杂数据类型是先调用 valueOf 方法,时间对象是先调用 toString 方法2、改成 return [1,2,3],得到的返回值是 9toString

说明:执行 valueof 后都来执行 toString

13.javascript 的 typeof 返回哪些数据类型

7 种分别为 string、boolean、number、Object、Function、undefined、symbol(ES6)、13.javascript 的 typeof 返回哪些数据类型

7 种分别为 string、boolean、number、Object、Function、undefined、symbol(ES6)、

14. 在 css/js 代码上线之后开发人员经常会优化性能,从用户刷新网页开始,一次 js 请求一般情况下有哪些地方会有缓存处理?

dns 缓存,cdn 缓存,浏览器缓存,服务器缓存。14. 在 css/js 代码上线之后开发人员经常会优化性能,从用户刷新网页开始,一次 js 请求一般情况下有哪些地方会有缓存处理?

dns 缓存,cdn 缓存,浏览器缓存,服务器缓存。


15.列举 3 种强制类型转换和 2 种隐式类型转

强制(parseInt,parseFloat,Number)、隐式(+ -)15.列举 3 种强制类型转换和 2 种隐式类型转换

强制(parseInt,parseFloat,Number)、隐式(+ -)

16.你对闭包的理解?优缺点?

概念:闭包就是能够读取其他函数内部变量的函数。三大特性:

函数嵌套函数。

函数内部可以引用外部的参数和变量。

参数和变量不会被垃圾回收机制回收。

优点:

希望一个变量长期存储在内存中。

避免全局变量的污染。

私有成员的存在。

缺点:

常驻内存,增加内存使用量。

使用不当会很容易造成内存泄露。

示例:function outer() {

var name = "jack";

function inner() {

console.log(name);

}

return inner;

}

outer()(); // jackfunction sayHi(name) {

return () =› {

console.log(`Hi! ${name}`);

};

}

const test = sayHi("xiaoming");

test(); // Hi! xiaoming虽然 sayHi 函数已经执行完毕,但是其活动对象也不会被销毁,因为 test 函数仍然引用着 sayHi 函数中的变量 name,这就是闭包。

但也因为闭包引用着另一个函数的变量,导致另一个函数已经不使用了也无法销毁,所以闭包使用过多,会占用较多的内存,这也是一个副作用。解析:由于在 ECMA2015 中,只有函数才能分割作用域,函数内部可以访问当前作用域的变量,但是外部无法访问函数内部的变量,所以闭包可以理解成“定义在一个函数内部的函数,外部可以通过内部返回的函数访问内部函数的变量“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。16.你对闭包的理解?优缺点?

概念:闭包就是能够读取其他函数内部变量的函数。三大特性:

函数嵌套函数。

函数内部可以引用外部的参数和变量。

参数和变量不会被垃圾回收机制回收。

优点:

希望一个变量长期存储在内存中。

避免全局变量的污染。

私有成员的存在。

缺点:

常驻内存,增加内存使用量。

使用不当会很容易造成内存泄露。

示例:function outer() {

var name = "jack";

function inner() {

console.log(name);

}

return inner;

}

outer()(); // jackfunction sayHi(name) {

return () =› {

console.log(`Hi! ${name}`);

};

}

const test = sayHi("xiaoming");

test(); // Hi! xiaoming虽然 sayHi 函数已经执行完毕,但是其活动对象也不会被销毁,因为 test 函数仍然引用着 sayHi 函数中的变量 name,这就是闭包。

但也因为闭包引用着另一个函数的变量,导致另一个函数已经不使用了也无法销毁,所以闭包使用过多,会占用较多的内存,这也是一个副作用。解析:由于在 ECMA2015 中,只有函数才能分割作用域,函数内部可以访问当前作用域的变量,但是外部无法访问函数内部的变量,所以闭包可以理解成“定义在一个函数内部的函数,外部可以通过内部返回的函数访问内部函数的变量“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354