【JavaScript】——javascript牛客专项练习错题合集

答:

var b = function(){
    alert(this.a); 
},
obj = {
    a:1,
    b:b // 把函数独立出来 
};
var fun = obj.b;// 存储的是内存中的地址
fun();

虽然fun是obj.b的一个引用,但是实际上,它引用的是b函数本身,因此此时的fun()其实 是一个不带任何修饰的函数调用,所以this指向window


赋值语句右侧的表达式含有关系运算符、逻辑运算符,其运算符的优先级是:

关系运算符>逻辑运算符(先&&后||)。

        因此,先执行关系运算:4 >= 6,返回结果为false,

        再执行逻辑运算的&&:true && 1,返回结果为1,

        最后执行逻辑运算的||: false || 1 || false,

        false || 1的结果为1,1 || false的结果也为1,所以变量a的值为1,C选项正确。


变量可以使用短名称,如x,y;也可以是长名称,如information,construction
变量命名规则如下:
1、变量命名必须以字母、下划线”_”或者”$”为开头。其他字符可以是字母、_、美元符号或数字。
2、变量名中不允许使用空格和其他标点符号,首个字不能为数字
3、变量名长度不能超过255个字符。
4、变量名区分大小写。(javascript是区分大小写的语言)
5、变量名必须放在同一行中
6、不能使用脚本语言中保留的关键字、保留字、true、false 和 null 作为标识符。
截止到目前为止JS描述了一组具有特定用途的关键字,一般用于控制语句的开始或结束,或者用于执行特定的操作等。关键字也是语言保留的,不能用作标识符。if for switch  case  break  continue  while  var  function 


alert($(window).height()); //浏览器当前窗口可视区域高度
alert($(document).height()); //浏览器当前窗口文档的高度

alert($(document.body).height());//浏览器当前窗口文档body的高度 alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin
alert($(window).width()); //浏览器当前窗口可视区域宽度
alert($(document).width());//浏览器当前窗口文档对象宽度

alert($(document.body).width());//浏览器当前窗口文档body的高度 alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin


jQuery中:

width() 方法设置或返回元素的宽度(不包括内边距、边框或外边距)。

height() 方法设置或返回元素的高度(不包括内边距、边框或外边距)。

innerWidth() 方法返回元素的宽度(包括内边距)。

innerHeight() 方法返回元素的高度(包括内边距)。

outerWidth() 方法返回元素的宽度(包括内边距和边框)。

outerHeight() 方法返回元素的高度(包括内边距和边框)。



Symbol是不完整的构造函数,创建symbol对象时不需要new操作符,①式不会抛出异常;

symbol对象不能用于数据运算,包括+、-、*、/等,②式会抛出异常;

symbol对象的唯一作用是作为对象的属性名,这样可以防止属性因重名而覆盖,使用时必须用[],③式不会抛出异常;

使用Reflect.ownKeys()可以遍历对象的属性,包括symbol属性,④式不会抛出异常。 


Symbol 值不能与其他类型的值进行运算,会报错。

新的API:Reflect.ownKeys() 方法可以返回所有类型的键名,包括常规键名和 Symbol 键名

对象内部使用Symbol 值作为属性名的时候,必须要将值放在方括号


这里要理解所谓‘数组’其实是array类型对象的一个特殊作用,就是:我们可以对它进行一种模式的数据存储,但除此之外,它依然是一个对象

  • var arr = [‘1’,‘2’] //这本质上是一系列操作:得到一个数组对象;调用了它的数组方法存入了一些数据,arr.length根据存入数据的数目被修改
  • arr.length,对arr对象的length属性进行一个访问
  • arr.foo = 'hello' 对arr对象创建一个属性,所以.foo 跟.length地位是并列的:就是arr的一个属性,同时arr的数组方法跟这些属性是毫不相关的

实际上Object(1.0)就是将数字“1.0”封装成它对应的包装类的一个对象实例

比如Number(1.0)。

所以目的是为了检测1是否在Number上

一开始1并不在Number原型链上所以返回false,直到添加了“Number[1]”这个下标属性之后才让1处于Number的原型链上,也因此返回了true。 


A选项:isIDCard=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/

C选项:isIDCard=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/
^:起始符号,^x表示以x开头
$:结束符号,x$表示以x结尾
[n-m]:表示从n到m的数字
\d:表示数字,等同于[0-9]
X{m}:表示由m个X字符构成,\d{4}表示4位数字

15位身份证的构成:六位出生地区码+六位出身日期码+三位顺序码
18位身份证的构成:六位出生地区码+八位出生日期码+三位顺序码+一位校验码


C选项的构成:
[1-9]\d{5}:六位出生地区码,出生地区码没有以0开头,因此第一位为[1-9]。
[1-9]\d{3}:八位出生日期码的四位年份,同样年份没有以0开头
((0\d)|(1[0-2])):八位出生日期码的两位月份,| 表示或者,月份的形式为0\d或者是10、11、12。
(([0|1|2]\d)|3[0-1]):八位出生日期码的两位日期,日期由01至31。
\d{4}:三位顺序码+一位校验码,共四位。
A选项的构成:
[1-9]\d{7}:六位出生地区码+两位出生日期码的年份,这里的年份指后两位,因此没有第一位不能为0的限制,所以合并了。 

后面的与C选项类似了。


对象a自身具有属性x,属性值为2,同时其原型对象上也有属性x,属性值为1;

对象b在初始化时,也是自身具有属性x,属性值为3。同时其原型对象为函数A的实例,同样具有属性x,由于没有传参,其属性x的值为undefined

当使用delete b.x时,对象b自身的x属性被删除,但是其原型对象上的x属性不会被删除

另外,根据对象属性查找的作用域链规则,访问对象属性时,会先查找对象自身的属性,如果不存在,才会继续在其原型对象上进行查找。

故a.x的返回结果为2,b.x的返回结果为undefined,C选项正确。 


选A、D。考察的是浏览器的内置对象管理模型,简称BOM(Browser Object Model)中的Histroy属性和方法。

  • length 返回浏览器历史列表中的URL数量。所以C中表述的长度信息是错误的。
  • back() 加载 history列表中的前一个URL
  • forward() 加载  history  列表中的下一个URL
  • go()  加载history列表中的某个具体页面所以B的表述刷新当前页面是错误的。

在Javascript定义一个函数一般有如下三种方式:

 1,函数关键字(function)语句:(最常用的方法)

function fnMethodName(x){
    alert(x);
}

 2,函数字面量(Function Literals):

 var fnMethodName = function(x){
    alert(x);
 } 

 3,Function()构造函数

var fnMethodName = new Function(‘x’,’alert(x);’) 

后两种都是把一个函数复制给变量fnMethodName,而这个函数是没有名字的,即匿名函数(拉达姆函数)。


类的所有实例方法均定义在类的原型对象上,因此,在类内定义的实例方法和在类的原型对象上定义方法是等价的,call()是实例方法,故A选项说法正确;

类的本质是函数,实际上,ES6中的类可以视为ES5中构造函数的另一种写法,所以②式的输出结果为function而不是Object,B选项说法错误;

p为类的实例对象,该对象有一个属性brand,属性值为华为,C选项说法正确;Object.assign(target, source)可将source源对象所有可枚举的属性(或方法)分配给target对象,所以可以使用Object.assign(Phone.prototype,{playGame,photo})为类一次性添加playGame和photo两个实例方法,D选项说法正确,不符合题意。


A.  className 属性设置或返回元素的 class 属性。获取属性值:          HTMLElementObject.className;设置属性值:HTMLElementObject.className=classname

B.  tagName 属性返回元素的标签名。HTML 返回 tagName 属性的值是大写的。element.tagName

     tagName()是用来获取当前标签名的方法,  而非设置标签。

     tagName只可读不可写

C.  innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML。HTMLElementObject.innerHTML=text

D.  id 属性置或者返回元素的 id。HTMLElementObject.id=id


 commonJS四个重要环境变量:

        requireexportsmoduleglobal

浏览器不兼容CommonJS的根本原因,在于缺少四个Node.js环境的变量。

  • module
  • exports
  • require
  • global

只要能够提供这四个变量,浏览器就能加载 CommonJS 模块。



考察知识点:逗号表达式只有最后一项是有效的,即对于i<10,j<6; 来说,判断循环是否结束的是 j < 6;而对于 j<6,i<10; 来说,判断循环是否结束的是 i < 10。

1

2

3

4

5

var k = 0;

for(var i=0,j=0;i<10,j<6;i++,j++){

  k += i + j;

}

console.log(k)    // 打印结果为 30

1

2

3

4

5

var k = 0;

for(var i=0,j=0;j<6,i<10;i++,j++){

  k += i + j;

}

console.log(k)    // 打印结果为 90


  • parseFloat 解析一个字符串,并返回一个浮点数
  • toFixed 把数字转换为字符串,结果的小数点后有指定位数的数字
  • Math.round 把一个数字舍入为最接近的整数
  • toPrecision 把数字格式化为指定的长度
// parseFloat(),解析一个字符串,并返回一个浮点数。
// toFixed把数字转换为字符,结果的小数点后有指定位数的数字,按四舍五入取值
var num = new Number(15.7857);
var a = num.toFixed(); //16 无参数,表示小数点后面位数为0位,然后四舍五入
var b = num.toFixed(1);//15.8
var c = num.toFixed(3);//15.786
var d = num.toFixed(10);  //多出的补0

//toPrecision()把数字格式化为指定长度
var f = num.toPrecision();//15.7857,无参数,返回原数字
var g = num.toPrecision(1);//2e+1,参数小于整数部分位数,返回科学计数
var h = num.toPrecision(3);//15.8,也是有四舍五入
var i = num.toPrecision(10);//15.78570000,长度不够补0

XML 不是 HTML 的替代。

XML 和 HTML 为不同的目的而设计:

XML 被设计为传输和存储数据,其焦点是数据的内容。

HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。


函数提升优先级高于变量提升不会被同名变量声明覆盖但是会被变量赋值后覆盖

在本题中,函数a和同名变量a会先进行提升,之后变量a又被赋值为10,再输出a的typeof值,此时a的值为10,类型为number,A选项正确。 


A:在setTimeout()定时器中,this指向Window对象,A选项不符合题意;

B:通过new Star()来调用Star函数,由于使用new绑定,Star函数内部的this指向new创建的实例,而非Window对象,B选项符合题意;

C:箭头函数不会与this进行绑定,其this指向取决于该箭头函数同级作用域的this指向,又由于对象不能形成自己的作用域,因此其作用域为全局作用域,this指向Window对象,C选项不符合题意;

D:立即执行函数的this指向Window对象,D选项不符合题意。 


选A。该题考察的是JS解析顺序

会被javascript编译器处理为:

//variable hoisting变量提升
var foo;//foo#1
var num;
 
//function declaration hoisting函数声明提升
function foo(x, y){//foo#2
   return x + y;
}
 
//function expression NOT hoisted函数表达式不会被提升
foo =function(x, y){//foo#3
   return x - y;
}
 
num = foo(1, 2);//这里使用foo#3

规则

1. 变量声明、函数声明都会被提升到作用域顶处;
2. 当出现相同名称时,优先级为:变量声明(foo#1) < 函数声明(foo#2) < 变量赋值(foo#3)

因此,num计算时是用的foo#3。答案为-1。


如果参数的小数部分等于0.5,则舍入到下一个在正无穷方向上的整数

  • 所以该题Math.round(11.5)=12,Math.round(-11.5)=-11,两者相加为1;

Math.round()函数返回一个数字四舍五入后最接近的整数

如果参数的小数部分大于0.5,四舍五入到相邻的绝对值更大的整数

如果参数的小数部分小于0.5,四舍五入到相邻的绝对值更小的整数

如果参数的小数部分等于0.5,四舍五入到相邻的在正无穷(+∞)方向上的整数。

例:

x=Math.round(2019.49) ;      //2019

x=Math.round(2019.5);         //2020

x=Math.round(-2019.5);        //-2019

x=Math.round(-2019.51);      //-2020


对于“+”运算,如果一端为字符串,则另一端会被转为字符串进行字符串之间的连接,因此C选项结果为1231;

如果一端为Number类型,另一端为原始数据类型,则另一端会被转为Number类型,再相加null会被转为0,A选项结果为123,undefined会被转为NaN,结果也为NaN,因此D选项正确;

B选项,123/0结果为Infinity。 

JavaScript 中,允许 0 作为除数,只有 0/0 结果是 NaN,其他数值 /0 结果都是 Infinity


A. concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

B. append() 方法在被选元素的结尾(仍然在内部)插入指定内容

C. appendTo() 方法在被选元素的结尾(仍然在内部)插入指定内容。

D. pop() 方法用于删除并返回数组的最后一个元素。


A、Fun() 把 class 当成方法来用? var fun = new Func() 这样用就对了

        类必须使用new调用,否则会报错。

B:export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

// 报错
export 1;
// 报错
var m = 1;
export m;


//正确写法
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m};
// 写法三
var n = 1;
export {n as m};

上面两种写法都会报错,因为没有提供对外的接口。第一种写法直接输出 1,第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。

D:A模块对外暴露了一个对象,引入的时候需要使用解构赋值

import {readFile} from ‘A'
        在A模块中 export {  readFile  } 后,(注意:这里A模块导出的是一个对象)

        在B模块中 import {  readFile  } from ‘A’   可以获取到readFile。(注意:这里要给对象进行解构赋值)


6(编码相关)+ 2(数据处理)+ 4(数字相关)+ 1(特殊)

编码相关:

    escape()、unescape()、encodeURI()、decodeURI()、

    encodeURIComponent()、decodeURIComponent()

数据处理:

    Number()、String()

数字相关:

    isFinite()、isNaN()、parseFloat()、parseInt()

特殊:

    eval()


setTimeout来自于window


回调函数,这是异步编程最基本的方法。

事件监听,另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。

发布/订阅,上一节的"事件",完全可以理解成"信号"。

Promises对象,Promises 对象是CommonJS 工作组提出的一种规范,目的是为异步编程提供统一接口。 


“同步模式”和“异步模式”:

(1)同步模式:就是后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。

(2)异步模式:完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

JavaScript中实现异步编程模式的4种方法,回调函数事件监听发布/订阅Promises对象

(1)回调函数:这是异步编程最基本的方法,优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。

        例:假定有两个函数f1和f2,后者等待前者的执行结果,如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。

(2)事件监听:任务的执行不取决于代码的顺序,而取决于某个事件是否发生。优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以”去耦合”(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变

得很不清晰。

        例:为f1绑定一个事件,当f1发生done事件,就执行f2。

(3)发布/订阅:我们假定,存在一个”信号中心”,某个任务执行完成,就向信号中心”发布”(publish)一个信号,其他任务可以向信号中心”订阅”(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做”发布/订阅模式”(publish-subscribe pattern),又称”观察者模式”(observer pattern)。

这种方法的性质与”事件监听”类似,但是明显优于后者。因为我们可以通过查看”消息中心”,了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

(4)Promises对象:是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

        例:f1的回调函数f2,f1().then(f2);


document.querySelectorAll('file')[0]获取的是第一个标签名为file的元素,而不是input标签,A选项错误;

document.getElementById(file')返回的是id属性为file的节点,而不是数组,B选项错误,D选项正确;

document对象没有getElementByTagName()方法,C选项错误。 


 对象在调用方法和属性时依靠原型链的顺序进行查找,先从自身查找,然后是构造函数的原型对象,接着是Object的原型对象,一旦找到时停止查找,找不到则返回undefined。

同时,原型对象中的this仍然指向实例对象,而非原型对象,在本题中,实例对象先调用原型对象的getAge()方法,然后输出age属性值,由于该实例对象已经有age属性,同时其原型链中,原型对象和原型对象的原型对象即Object对象均有age属性,依据上述查找规则,最终输出结果为实例对象的age,即为24。


函数内部var声明的变量也会发生变量提升,但只会提升至本作用域最上,不会跨作用域,因此函数执行完毕后,外层是无法访问函数作用域内的变量。 


a是形参,属于局部变量,不影响全局变量a的值,因此输出的a是全局变量的值10

function test(){
return a=a+10;
}
var a=10;
test();
console.log(a);
//这样输出得就是20了。之前的话是因为a只是作为形参传入函数,
//且只是改变了函数内部局部变量a的值,不影响全局变量a,

e.preventDefault() 是用来阻止默认事件的,不是阻止事件冒泡

事件冒泡应该是 e.stopPropagation()

知识点有四个

1.事件冒泡。

2.addEventListener是有第三个可选参数的,默认为false,意思是不在捕获阶段提前触发。

3.preventDefault()是阻止事件的默认操作,比如点submit之后会提交表单。类似的属性是returnValue=false

4.阻止冒泡的方法是,e.stopPropagation()或者e.cancelBubbe


几个常见的事件的方法

preventDefault()    取消事件默认行为,如阻止点击提交按钮时对表单的提交(本题中click并没有什么默认行为)

stopImmediatePropagation()   取消事件冒泡同时阻止当前节点上的事件处理程序被调用,影响当前的事件***

stopPropagation()   取消事件冒泡,不影响事件***

cancelBubbe()     取消事件冒泡

returnValue()      取消事件默认行为


 1、什么是迭代器?

迭代器是一个对象,需要满足:对象内部有方法next,next方法要求返回对象{done: true或false, value:值 }
!!!(注意区分:迭代器 和可迭代对象 是不一样的)

2、一个迭代器是如何遍历的?

1

2

3

4

5

6

7

8

const arr = ["a","b"]

// 数组默认是一个可迭代对象,就好比题目中的对象x

const iterator = arr[Symbol.iterator]() // 拿到迭代器

console.log(iterator.next());

console.log(iterator.next());

// { value: 'a', done: false }

// { value: 'b', done: false }

// { value: undefined, done: true }

不难看出,value表示每次遍历的值,而done表示遍历是否完成

3、for...of...补充

for... of...的使用需要是一个可迭代对象,这道题的x,也是因为是一个可迭代对象,所以才可以用的for...of
可以理解为:for..of..就是上面调用iterator.next()的语法糖,直到最后done为true表示遍历完了。...

4、什么是可迭代对象?

如果一个对象,实现了[Symbol.iterator]方法,且这个方法返回一个迭代器(这个方法就是一个生成迭代器的函数,比如题目中的foo函数)

1

2

3

4

5

6

7

8

9

10

function foo(x = 6) {

    return { // 返回一个迭代器

        next: () => {

            control(x);

            return {done: !x, value: x&&x-- };

        }

    }

}

// x成为可迭代对象

x[Symbol.iterator] = foo

5、得结果

1

for(let i of x) console.log(i);

既然x是可迭代对象,那他可以用for...of...进行遍历,遍历时会自动去执行foo,foo返回迭代器。

上面也说了for...of...的遍历就是:一次次的调用iterator的next,拿到value,直到next返回的done为true。

1

2

3

4

5

6

7

8

function foo(x = 6) {

  return {

    next: () => {

      control(x);

      return {done: !x, value: x && x--};

    }

  }

}

里层next函数调用的x是foo的参数x(闭包),x默认赋值为6,通过题目中的control函数可以知道,x=3的时候,就抛错,结束了。

当x=6,return{ done:!x, value: x && x--}
done为false,value是x && x--

6 && 6,  &&前者为true,value结果取后者,return { done:false, value : 6},

然后x--变成5

继续。。。。最后结果
6,5,4,抛错 




普通函数,this永远指向它的调用者;箭头函数,this指向定义时的上下文

obj.print() ===> obj调用的普通函数,this指向调用者obj这个对象,所以this.a就是obj.a,即为 'o';

obj.print2() ===> obj调用的箭头函数,this指向上下文,即全局作用下的window,所以this.a就是window.a,即为 'w';
let p = obj.print; p() ===> p是在全局作用域下的,p指向了print(){}函数的地址,执行时是在全局作用域下调用的,所以this指向window,this.a就是window.a,即为 'w';

let p2 = obj.print2; p2() ===> 虽然p2是在全局作用域下的,但是p2指向了print2: () => {}箭头函数的地址,所以this指向print2函数定义时的上下文,即window,this.a就是window.a,即为 'w';

所以,最终输出为:'o', 'w', 'w', 'w'


布尔和数字会转为数字、字符串和数字会转为数字

A、

boolean值会把true,false隐式转换为数字

1 == true   // 布尔值会转成number true即为1 所以结果是true

2 == true   // 布尔值会转成number true即为1 所以结果是false
3 == true   // 布尔值会转成number true即为1 所以结果是false
1 == false  // 布尔值会转成number false即为0 所以结果是false

0 == false  // 布尔值会转成number false即为0 所以结果是true

B、数字、字符串2会转换成数字2在和数字2进行比较 。
== js会优先选择将字符串转成数字==

C、Javascript规范中提到, 要比较相等性之前,不能将null和undefined转换成其他任何值,并且规定null和undefined是相等的。

null和undefined都代表着无效的值。

D、

isNaN() 函数用于检查其参数是否是非数字值。

如果参数值为 NaN 或字符串、对象、undefined等非数字值则返回 true, 否则返回 false。

isNaN()的一些例子:

isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true


status属性返回状态码,为一个数字。响应的HTTP状态

statusText属性返回状态码以及描述,字符串。HTTP状态的说明

并没有statusCode....       ajax 里并没有statusCode;

ajax响应:

    responseText:作为响应主体被返回的文本

    responseXML:如果响应的内容类型是"text/xml"或者"application/xml", 这个属性中将保存包含着响应数据XML DOM文档


XMLHttpRequest对象的readyStatestatus的几种状态码表示的意思:

readyState有五种状态:

0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法;

1 (载入):已经调用open() 方法,但尚未发送请求;

2 (载入完成): 请求已经发送完成;

3 (交互):可以接收到部分响应数据;

4 (完成):已经接收到了全部数据,并且连接已经关闭。

status实际是一种辅状态判断,只是status更多是服务器方的状态判断。

关于status,由于它的状态有几十种,我只列出平时常用的几种:

1xx——信息类,表示收到Web浏览器请求,正在进一步的处理中。如,100:客户必须继续发出请求;101:客户要求服务器根据请求转换HTTP协议版本

2xx——成功,表示用户请求被正确接收,理解和处理。例如,200:OK;201:提示知道新文件的URL

3xx——重定向,表示请求没有成功,客户必须采取进一步的动作。如,300:请求的资源可在多处得到;301:删除请求数据

4xx——客户端错误,表示客户端提交的请求有错误。如,404:NOT Found,意味着请求中所引用的文档不存在。

5xx——服务器错误,表示服务器不能完成对请求的处理。如,500,服务器产生内部错误



A.严格模式下不允许未声明赋值uname = 'window'当然报错❌;严格模式下的this在函数体内不会默认指向window,而是指向undefined。 但是setTimeout中函数内的this指向window,并不是像函数一样this是undefined,所以这里的setTimeout不会抛出错误

B.指向undefined。undefined.uname 当然报错❌

C.严格模式下函数参数不能同名 报错❌

D.在严格模式下,构造函数中的this指向构造函数创建的对象实例,this指向person{},但是person对象没有uname这个属性,因此为undefined。构造函数实例化对象的this指向的是实例化对象本身,而实例化对象下没有uname这个属性,所以得到undefined,没有报错。


1)在严格模式下,给未声明的变量赋值,会导致抛出ReferenceError,报错。简而言之,严格模式下变量必须用关键字声明后才能使用。

2)严格模式下,普通函数的this指向undefined。

3)严格模式下,立即执行函数的this指向undefined。

4)严格模式下,setTimeout中函数的this指向的window(与普通函数不同)。

5)严格模式下,函数的参数不能同名,否则报错。

6)严格模式下:构造函数的this指向undefined,但是构造函数实例化对象的this指向的是实例化对象本身


这是考察JS中提升(hoist)的问题,也就是变量提升和函数提升

要注意几个点

  • 1.函数声明提升优先级高于变量声明提升
  • 2.提升就是声明(变量/函数)提至当前作用域的最顶部,赋值语句留在原地
  • 3.函数创建有3个形式,函数声明函数表达式 以及 new Function构造函数
  • 4.只有函数声明才有函数提升。...其实2个都有提升,表达式提升的是变量了。
//原来的代码
var a = 2;
function fn(){
        b();
        return ;
        var a = 1;
        function b(){
            console.log(a);
        }
}
fn();

//实际上的代码
var a = 2;
function fn(){
    function b(){
      console.log(a);
    }
    var a //变量声明提升,默认赋值为undefined
    b(); //执行函数b,在当前作用域找到a,值为undefined
    return;//return后面的语句不再执行,a没有被赋值为1
    a = 1; //在原来的位置才会赋值,但不会执行到这里
}
fn();

函数声明和函数表达式的区别(以及提升的不同)

  • 就是function左边没有东西就是函数声明,有就是表达式
//函数声明
  function f1(){
    console.log('我是函数声明')
  }
  //函数表达式
  var f2 = function () {
    console.log('我是函数表达式')
  }

函数发生提升后
// 函数声明--提升
function f1() { 
  console.log('我是函数声明')
}
var f2;
f1() //'我是函数声明'
f2() //error:f2 is not a function
// 函数表达式
f2 = function() {
  console.log('我是函数表达式')
}

JS中所有声明(val / let / const /function() /class / function*)  都存在提升,不过像let const class这些因为TDZ的原因‘表现’得像没有提升。


前提是myobj是一个对象,只是存在与不存在的问题,几种表示方法:

1、!obj

2、!window.obj

3、typeof myObj == "undefined(判断对象是否有定义,已定义未赋值,返回true)

4、myObj == undefined(已定义未赋值。返回true)

5、myObj === undefined (已定义未赋值,返回true)

6、!this.hasOwnProperty('myObj'))(判断是否为顶层对象的一个属性)

7、myobj == null(注意null与undefined的区别,ull指的是已经赋值为null的空对象,即这个对象实际上是有值的,而undefined指的是不存在或没有赋值的对象。)

只有null===null时,结果为true;

其余类型与null,比较时结果都为false。


选A。

  • exec() 方法用于检索字符串中的正则表达式的匹配

  • 返回值
    返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。

  • 所以"e".exec("hello")中,"e"是正则表达式,"hello"是检索的字符串。在"hello"字符串中,能够匹配到"e"。因此document.write("e");
    最后结果为e。

  • exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比 test() 方法以及支持正则表达式的 String 对象的方法更为复杂。

  • 如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。

  • 此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。

  • 除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看得出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。  

  • var str="the name 123 and 456";
    var reg=/\d/g;
    reg.exec(str); //["1", index: 9, input: "the name 123 and 456"]       
  • 但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。


通过原生js document.getElementById("button1").setAttribute 属性设置禁用时,第二个参数不论设置什么样的值,都能进行禁用。应该js在检测标签时只要有disabled时,便设置为禁用。

D答案的第二个参数不论是布尔值还是字符串还是数字,最终的结果都是禁用。

当然,可以通过removeAttribute去掉属性来解除禁用。

①disabled和readOnly都是表单的公有属性, readOnly是只读, disabled是禁用。这里问的是禁用,所以是disabled。

②还有就是题目中的 readOnly写成了 readolny


onfocus:元素获得焦点; onblur:元素失去焦点。 


 本题属于ES5继承中的共享原型,由于Son和Father的原型对象指向同一对象,这样就导致了不管是修改Father原型对象还是Son原型对象的属性或方法,另一个的原型对象也会跟着修改。

由于getAge()方法均定义在原型对象,后定义的getAge()方法会覆盖先定义的getAge(),所以最终输出结果均是18,A选项正确。

function Father(age) { //此时Father.prototype = { constructor: function Father(){}}
    this.age = age
}
function Son(age) { //此时Son.prototype = { constructor: function Son(){}}
    Father.call(this);
}

Son.prototype = Father.prototype;
//此时Son.prototype = { constructor: function Father(){}}   
//此时Father.prototype = { constructor: function Father(){}}
//现在,Son和Father的prototype指向同一个对象,也就是指向堆里的同一个地址


Father.prototype.getAge = function () { console.log(40) },//堆里加一个getAge属性
//此时:
// Father.prototype = {
//     constructor: function Father(){}
//     getAge: function(){console.log(40);}
// }
//特别注意,因为Son和Father的prototype指向同一个对象(堆里同一个地址),所以
// Son.prototype = {
//     constructor: function Father(){}
//     getAge: function(){console.log(40);}
// }

Son.prototype.getAge = function () { console.log(18) };
//此时:
// Son.prototype = {
//     constructor: function Father(){}
//     getAge: function(){console.log(18);}
// }
//因为Son和Father的prototype指向同一个对象(堆里同一个地址),所以
// Father.prototype = {
//     constructor: function Father(){}
//     getAge: function(){console.log(18);}
// }


var father = new Father(40); // father = { age: 40 } 
var son = new Son(18); //如果构造函数Son里没有Father.call(this);  那么此时 son = {}
//但是,构造函数Son里有Father.call(this);  然后 son = { age: undefined } (暂时不太明白这是为什么)

//以上结束后father = { age: 40 } 
//以上结束后son = { age: undefined } 


father.getAge(); //father里只有一个age,没有getAge方法,去原型Father.prototype里找, 执行函数console.log(18)
son.getAge();//son里只有一个age,没有getAge方法,去原型Son.prototype里找, 执行函数console.log(18)

//本题跟传入的age没有关系,因为getAge方法里没有任何对age的处理,只是执行一个console.log()

一、try catch 还有finally的用法😊

1、try catch 还有finally的基本概念

1)try块一共有三个关键字try catch 还有finally;
2)finally 语句无论 try 和 catch 执行结果如何都会执行;(本题考到的知识点)
3)catch是捕获到 try语句块里的错误才会执行;

注意: catch 和 finally 语句都是可选的,但你在使用 try 语句时必须至少使用一个(也就是try必须搭配catch或者finally)。

2、try catch 还有finally代码块中 有return时 的执行情况(本题考到的知识点)

例一:

        如果try语句没有使用finally,则返回try语句中return的东西,

        函数try...catch语句之外的return 就不执行了

 function testFinally() {
     var num = 10;
     try {
         return num + 1;//return这里的值11
     } catch (err) {
         console.log(err)
     }
     return num + 5; //无效,没执行到这,try...catch执行之后就跳出了
                     //除非try...catch...finaly语句中没有return
 }
 console.log(testFinally());//11

例二:

        如果try语句后面有finally,try中的return不会跳出函数,因为一定要进入finally语句

        函数try...finally语句之外的return 就不执行了

function testFinally() {
    var num = 10;
    try {
        return num += 1; //return右边的语句正常执行,计算得num=11
    } finally {        //有finally,try中的return不会跳出函数,因为一定要进入finally语句
        return num + 20; //11+20=31
    }
    return num + 5; //无效,没执行到这,try...finally执行之后就跳出了
}
console.log(testFinally());// 31

例三:(可看完后面的break知识点,再来看这个例子)
        如果try语句后面有finally,try中就算有break用来跳出语句块,也不管用
        只要有finally,不管try和catch语句中执行什么,一定会进入finally语句

function testFinally() {
    var num = 10;
    aaa: try{
        break aaa; //有break按理说应该要跳出 try...finally... 这个语句块了
                   //但是不管用,因为后面有finally,一定要进入finally语句
    } finally {         
        return num + 20; //10+20=30
    }
    return num;//失效,没执行到这
}
console.log(testFinally());// 30

重点记住:try...catch...finally语句中,只要有finally存在,不论什么情况,finally都会执行。

二、break 的用法😄

1、break语句用于跳出 switch语句 或者 循环语句( for 、for..in、while、do...while) 

   语法:break;

1)当break语句用于switch语句时,会跳出switch代码块,终止执行switch代码。
2)当break语句用于循环语句时,会跳出整个循环,不再执行后续剩余的循环。
3)注意break与continue的区别:continue会跳出本轮循环,继续执行后续剩余的循环

2、break语句也可用于标签引用,用于跳出标签指向的代码块。(本题考到的知识点)

   语法:break labelName;
例一:

        在标签引用中使用 break 语句,用于跳出标签代码块:

var cars = ["BMW", "Volvo", "Saab", "Ford"];
var text = "";
list: { //list标签引用
    text += cars[0];
    text += cars[1];
    text += cars[2];
    break list; //在标签引用中使用 break 语句,用于跳出list代码块,不再执行list代码块里剩余的代码
    text += cars[3];
}
console.log(text);//BMW Volvo Saab

例二:

        在标签引用中使用 break 语句,用于跳出嵌套循环:

var text = "";
var i, j;
 
Loop1: for (i = 0; i < 3; i++) { // 第一个循环标签 "Loop1"
    Loop2: for (j = 10; j < 15; j++) {// 第二个循环标签 "Loop2"
        if (j == 12) {
            break Loop2;//跳出Loop2代码块
        }
        console.log(i, j)
    }
}
//i=0,j=10
//i=0,j=11
//i=1,j=10
//i=1,j=11
//1=2,j=10
//i=2,j=11

三、本题过程😁

var i = 100;
function foo() {     //bbb 是 try... finally...这个代码块
    bbb: try {        //break语句的标签引用,用于跳出 bbb标签 代码块
        console.log("position1");//打印position1
        return i++;  } //继续执行return右边的代码,此时i++为100,i为101
    finally {                //只要有finally,不管try语句里写啥(return,break之类的失效),都会执行finally语句
        break bbb;     //跳出bbb标签代码块
    }                   //跳出try...finally后,因为finally中没有return,故可执行后续代码
                           //如果finally中有return,则无法执行后续代码了
    console.log("position2");//打印position2
    return i;//返回i,i=101
}
foo();

在块中多个语句执行时,一般后者会覆盖前者,但是;和break的返回值都是empty,无法覆盖任何值。而3覆盖了4,10最终又覆盖了3,因此最终的结果是10,空不会覆盖10。

 eval 将会返回对最后一个表达式的求值结果。


  • $(父元素).append(子元素)
  • $(子元素).appendTo(父元素)

在旧浏览器(ie7-)下用 join 会更高效。

  1. 在现代浏览器,尽量用"+",更高效。

  2. 当然,在少数现代浏览器里 “+” 不一定会比 join 快(如,safari 5.0.5,opera 11.10)

  3. 本身是字符串数组的,直接 join 会更好。

  4. 在"+"与concat之间,当然是优选使用"+",方便又直观又高效。


 class的声明特征跟const和let类似,都是作用于块级作用域,预处理阶段则会屏蔽外部变量。因此在声明之前访问变量a都会报错,在声明之后访问才可以正常输出。

class和let一样都有暂时性死区,在被声明前无法访问

也就是在当前作用域能找到,但是要在声明后才能访问
es6中的class和let const一样都不存在提升
(实际存在提升,只是因为TDZ的作用,并不会像var那样得到undefined,而是直接抛出错误

原来的代码
var a = 1;
function test(){
    //console.log(a) 位置A
class a {}
   // console.log(a) 位置B
}
test();

实际上提升后的
var a = 1;
function test(){
    console.log(a) 位置A //在test()作用域内找得到a
//是一个class但是存在TDZ暂时性死区,访问报错
    class a {}
    console.log(a) 位置B //a已经声明创建出来了
}
test()

 选A。JavaScript有五个基本类型:number、string、null和undefined。其中null和undefined以外,其他三个具有所谓的包装对象,可以通过内置构造函数Number()、String()、Boolean()创建包装对象。 选项A,javascript中[]转化为布尔值为true,即Boolean([])返回true,加上两个非符号返回仍为true。 选项B,===表示等同符,当两边值类型相同时直接比较值,若类型不同返回false。int类型和char类型不同所以返回false。 选项C,null表示空值,undefined未定义,直接返回false 选项D,Boolean('')返回false,加上两个非符号,最终结果为false


 js传参包括基本数据类型传参和复杂数据类型传参,基本数据类型传参实际上是复制值传递,函数对形参的处理不会影响到外面的实参,而复杂数据类型传参是引用传递,即把数据的地址复制一份后传递到函数中,此时形参和实参指向同一地址的对象,对于形参的修改会影响到实参。在本题中,obj是使用引用传递,num是使用值传递,因此最终结果为B选项。


Date.now() 方法返回自1970年1月1日 00:00:00 UTC到当前时间的毫秒数。 


● 首先, js有变量提升和函数提升,指的是用 var声明变量 或用 function 函数名(){  } 声明的,会在 js预解析 阶段提升到顶端;(es6的let  和 const 不会提升)

● 其次,函数提升优先级 高于 变量提升

● 注意, 相同作用域时声明变量而不赋值则还是以前的值, 而子作用域声明不赋值则函数内该值为undefined,因为声明了私有变量

让我们看看下面的代码

console.log(foo); 
var foo = 1  //变量提升
console.log(foo)
foo()
function foo(){ //函数提升
   console.log('函数')
}

等价于:

function foo(){ //提到顶端
   console.log('函数')
}
var foo  
console.log(foo) //输出foo这个函数,因为上面foo没有被赋值,foo还是原来的值 
foo = 1;  //赋值不会提升,赋值后 foo就不再是函数类型了,而是number类型
console.log(foo) //输出1
foo() //这里会报错,因为foo不是函数了

A 选项主要是 URI 编码,主要是对特殊字符进行转义,具体规则可以查阅相关资料

其实可以简单理解成转义,类似于在字符串中输出\需要写成\\一样,%在这里就是一个转义字符。只有转义字符的开头却没有要被转义的东西,肯定是会报错的。

B 选项主要是变量提升,并且函数优先于变量进行提升。其他人已经说得很好了。

C 选项需要 catch 被 reject 的 Promise,才能不抛出错误。这里的错误类似于执行了一个会抛出异常的操作,但却没有捕获。这是一种可以正常运行的写法:

Promise
    .reject(123)
    .catch(err => console.log(err))
    .finally(a => console.log(a));

D 选项两个都是var的话下面会直接覆盖上面的,let的话重复定义会报错。因为 let 的 TDZ(“暂时性死区”),在 let 的作用域中无法重复声明,也无法在声明语句之前使用(没有变量提升)。简而言之,在 let 语句出现之前,都是无法使用该变量的。

补充一点。这种情况下是可以正常运行的:

var a = 1;
{
    let a = 2;   
}
console.log(a);

答案是A。

1<<4   左移相当于1*2^4=16

a^=16-1=15

a=a^15=10^15

^ 异或运算:

10的二进制00001010

15的二进制00001111

========>00000101  转成十进制:5

(按位异或运算,同为1或同为0取0,不同取1) 


\w用于匹配数字、字母或者下划线,A选项错误;/a?/表示匹配0个或者1个a,B选项错误;i修饰符表示忽略大小写,C选项正确;表示对第一个捕获组的引用,应使用\1,D选项错误。 


var foo = {n:1};
(function(foo){            //形参foo同实参foo一样指向同一片内存空间,这个空间里的n的值为1
    var foo;               //优先级低于形参,无效。
    console.log(foo.n);    //输出1
    foo.n = 3;             //形参与实参foo指向的内存空间里的n的值被改为3
    foo = {n:2};           //形参foo指向了新的内存空间,里面n的值为2.
    console.log(foo.n);    //输出新的内存空间的n的值
})(foo);
console.log(foo.n);        //实参foo的指向还是原来的内存空间,里面的n的值为3.

优先级:声明变量函数>普通函数>参数>变量提升



下面情况会导致reflow发生

1:改变窗口大小

2:改变文字大小

3:内容的改变,如用户在输入框中敲字

4:激活伪类,如:hover

5:操作class属性

6:脚本操作DOM

7:计算offsetWidth和offsetHeight

8:设置style属性


+表示出现至少一次b

*表示可以不出现b,也可以出现一次或多次

{n,m}表示最少出现n次b,最多出现m次b


不支持冒泡:妈(mouseenter)妈(mouseleave)不(blur)放(focus)心你(load,unload,resize) 


 undefined和null与任何有意义的值比较返回的都是false,但是null与undefined之间互相比较返回的是true。


if(x) 这里期望 x 是一个布尔类型的原始值,而 x 是一个对象,任何对象转为布尔值,都为得到 true切记!在 JS 中,只有 0,-0,NaN,"",null,undefined 这六个值转布尔值时,结果为 false)。

题目的第二部分,一定要注意 y = Boolean(0)而不是 y = new Boolean(0)。这两个有很大区别,用 new 调用构造函数会新建一个布尔对象,此处没有加 new,进行的是显示类型转换,正如上述第一条所说,0 转换布尔,结果为 false,所以此时 y 的值就是 false。如果加了 new,那么 y 就是一个 Boolean 类型的对象,执行 if(y) 时,对象转布尔,始终是 true,所以结果会与不加 new 的时候相反。


 

 首先明确this指向无法传递,所以函数p的this是指向window,同时因为let声明的变量不会挂载到window上所以是window下的a变量只能是undefined。至于obj.print方法this指向的是obj所以输出的是obj里面的变量a的值即o。


A选项,构造函数的原型对象中有一个constructor属性,指向构造函数本身,因此程序输出结果为构造函数,而不是undefined;B选项,sing方法是定义在构造函数上的静态方法,调用时使用Person.sing(),而不能实例对象来调用;C选项,getAge方法是定义在原型对象上,而原型对象上的方法可以使用实例对象来调用,原型对象方法中的this指向实例对象;D选项,使用p.age可以访问实例对象p的age属性,结果为18。


 NOSCRIPT标签用来定义在脚本未被执行时的替代内容。也可以用在检测浏览器是否支持脚本,若不支持脚本则可以显示NOSCRIPT标签里的innerText。

noscript:用以在不支持js的浏览器中显示替代的内容,这个元素可以包含能够出现在文档<body>中任何html元素,script元素除外。包含在noscript元素的内容只有在下列情况下才会显示出来
1.浏览器不支持脚本
2.浏览器支持脚本,但脚本被禁用

<body>  
...
  ...
  <script type="text/javascript">
    <!--
    document.write("Hello World!")
    //-->
  </script><noscript>Your browser does not support JavaScript!</noscript>...
  ...
</body>

JavaScript单线程的,浏览器实现了异步的操作,整个js程序是事件驱动的,每个事件都会绑定相应的回调函数。 


var str = 'acdaecad';
var obj = {};
for (var i = 0;i<str.length;i++){
            if (obj[str.charAt(i)]){ //判断是obj里是否有str里面某个字母的属性
                obj[str.charAt(i)]++;//如果有,给那个属性++
            }
            else {
                obj[str.charAt(i)] = 1;      //如果没有,给obj添加那个属性
        }
        }
var val1;
var val2 = 0;
for (var k in obj) { //for in 循环遍历对象,k是键(也就是对象的属性名) obj就是原对象
            if (obj[k] > val2){  //如果obj的属性值大于val2    里面a出现的最多。++次数最多,也就是3
                val2 = obj[k];   //val2等于obj的属性值 
                val1 = k;  //最后将属性名赋予  
            }
}
console.log(val1);所以最后输出a

程序一开始先把字符串str的单个字符作为对象obj的属性,属性值为单个字符在字符串str中的个数,即obj = {a: 3, c: 2, d: 2, e: 1},然后开始遍历对象obj,找出对象obj属性值最大的属性名,因此最终val1结果为属性a,val2为该属性对应的属性值3,该程序的执行效果即为找出字符串str中同一元素出现个数最多的字符以及对应的个数。


  1. Array.from(arr, mapfn,thisArg)方法,用于将两类可以把对象转换为真正的数组:类似数组的对象和可遍历的对象(部署了Iterator接口的,String,ES6新增的Map和Set)。可以传3个参数,其中第一个是数组,必传;第二个是一个函数(类似map函数),对数组元素进行操作后再返回数组,可选;第三个是对于this关键字的指向,可选。
  2. slice() 方法可从已有的数组中返回选定的元素。
    返回值:返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
    说明
    请注意,该方法并不会修改数组,而是返回一个子数组。如果想删除数组中的一段元素,应该使用方法 Array.splice()。
    所以在这里就是对集合A应用slice,返回一个新的数组,不对数组做任何改变。
  3. 展开运算符,把A集合的元素展开后,用数组[]承载,返回新的数组。
  4. map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
    map() 方法按照原始数组元素顺序依次处理元素。
    注意: map() 不会对空数组进行检测。
    注意: map() 不会改变原始数组。
    所以map方法返回了一个新的数组,并且数组中每个元素是A里面的元素。 

  • (()=>{}).length; 获取方法形参个数,形参为0
  • 1=0001 2=0010  按位与运算,同为1才为1,否则返回0
  • +[] 隐式类型转换,因为[]是对象,所以toPrimitive->valueOf->toString为'',结果就是+''===0
  • reduce对数组中的每个元素执行一个reducer函数(升序执行),将其结果汇总为单个返回值。reduce接受2个参数,回调函数和初始值。a为累计器累计回调的返回值,b为数组的每一项元素,传入初始值0->0-(1)->(-1)-2->(-3)-(-3)->0

arr.forEach()是循环遍历数组,它的参数是一个函数,每迭代一次数组,就执行函数一次,也就是,虽然在函数内部存在return语句,但是当执行return时相当于退出一次迭代,当前数组会继续下一次迭代,函数有两个参数,参数val1为数组的元素值,参数val2为数组元素对应的索引,因此正确答案为D选项。 

var arr = [2,1,3,5,9];
var count = 0;

arr.forEach((val1,val2)=>{//arr = [2,1,3,5,9];
        count++; //第一次循环count++为0
        if(count % 3 == 0){ //第一次循环count为1,不满足条件,不进入if条件里
            return;
        }
        console.log(val1);//第一次循环val1=2
})

arr.forEach((val1,val2)=>{//arr = [2,1,3,5,9];
        count++; //第二次循环count++为1
        if(count % 3 == 0){ //第二次循环count为2,不满足条件,不进入if条件里
            return;
        }
        console.log(val1);//第二次循环val1=1
})

arr.forEach((val1,val2)=>{//arr = [2,1,3,5,9];
        count++; //第三次循环count++为2
        if(count % 3 == 0){ //第三次循环count为3,满足条件,进入if条件里
            return;     //return跳出本次循环,不执行后续代码
        }
        console.log(val1);//第三次循环没执行到这
})

arr.forEach((val1,val2)=>{//arr = [2,1,3,5,9];
        count++; //第四次循环count++为3
        if(count % 3 == 0){ //第四次循环count为4,不满足条件,不进入if条件里
            return;         
        }
        console.log(val1);//第四次循环val1=5
})

arr.forEach((val1,val2)=>{//arr = [2,1,3,5,9];
        count++; //第五次循环count++为4
        if(count % 3 == 0){ //第五次循环count为5,不满足条件,不进入if条件里
            return;         
        }
        console.log(val1);//第五次循环val1=9
})

选择AD。

  1. A. readystatechange
    document有readyState属性来描述document的loading状态,readyState的改变会触发readystatechange事件.
    • loading
      文档仍然在加载
    • interactive
      文档结束加载并且被解析,但是像图片,样式,frame之类的子资源仍在加载
    • complete
      文档和子资源已经结束加载,该状态表明将要触发load事件。

因此readystatechange在onload之前触发。

  1. B.onpageshow
    onpageshow 事件在用户浏览网页时触发。
    onpageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发。

  2. C. beforeunload
    当浏览器窗口,文档或其资源将要卸载时,会触发beforeunload事件。这个文档是依然可见的,并且这个事件在这一刻是可以取消的.
    如果处理函数为Event对象的returnValue属性赋值非空字符串,浏览器会弹出一个对话框,来询问用户是否确定要离开当前页面(如下示例)。有些浏览器会将返回的字符串展示在弹框里,但有些其他浏览器只展示它们自定义的信息。没有赋值时,该事件不做任何响应。

  3. D.DOMContentLoaded
    当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。
    另一个不同的事件 load 应该仅用于检测一个完全加载的页面。因此DOMContentLoaded是HTML完全加载和解析完成之后发生的,发生时间点要早于load,选D。
    在使用 DOMContentLoaded 更加合适的情况下使用 load 是一个令人难以置信的流行的错误,所以要谨慎。
    注意:DOMContentLoaded 事件必须等待其所属script之前的样式表加载解析完成才会触发。

readystatechange 读取状态变化
pageshow 页面展示
beforeunload 页面退出
DOMContentLoaded dom内容加载完成

在js中,调用对象属性的方法包括使用点操作符或者中括号,使用对象.属性进行调用时,一般情况下,属性是不需要带引号的;而使用中括号进行调用时,属性一般是以字符串的形式,也可以是变量或者表达式,ABD选项的做法均正确,C选项的做法是错误,不能使用花括号来调用对象的属性。 


  • 任何使用 var 声明的属性不能从全局作用域或函数的作用域中删除。
    • 这样的话,delete操作不能删除任何在全局作用域中的函数(无论这个函数是来自于函数声明或函数表达式)
    • 除了在全局作用域中的函数不能被删除,在对象(object)中的函数是能够用delete操作删除的。
  • 任何用letconst声明的属性不能够从它被声明的作用域中删除。
  • 不可设置的(Non-configurable)属性不能被移除。这意味着像MathArrayObject内置对象的属性以及使用Object.defineProperty()方法设置为不可设置的属性不能被删除。

  1. parseInt() 函数可解析一个字符串,并返回一个整数。
    所以说,number类型的12.34发生隐式转换为string。
  2. 三元运算符,会判断?前的表达式为true或者false。所以number类型的0发生了隐式转换为boolean。
  3. +运算发生了字符串的隐式转化。原本number类型的1,和string类型的'1'进行了+运算,连接了字符串。返回'11'。
  • C选项:
    e是js里面指数的一种表示形式。也就是10的多少次方。
    2e1 等价于 2 *(10^1) = 20
    2e2 等价于 2 *(10^2)= 200
    0xaa是16进制的表示方法。相当于十进制的170。
    这里都是number类型,发生了数字的乘法运算:20*170,没有发生类型转换。

console.log(!!null);  //false
console.log(!!0);  //false
console.log(!!"0");  //true  这只是个字符串
console.log(!!undefined);  //false
console.log(!!"");  //false  //空字符串会返回false

 转换为false的值只有6种:false、“”(空字符串)、0和NAN、null、undefined。


注意区分属性和方法,也即有没有()括号。
详见:Node.parentNode - Web API 接口参考 | MDN
注意看左侧栏的属性和方法,并区分。
总结:
node节点有几个常用的属性

  • firstChild
  • lastChild
  • nextSibling:下一个兄弟节点
  • previousSibling:前一个兄弟节点

这些都是属性,都不需要添加括号的。



每个对象都有__ptoto__属性,但prototype属性是函数对象特有的


 1.第一个this.foo输出bar,因为当前this指向对象myObject。

2.第二个self.foo输出bar,因为self是this的副本,同指向myObject对象。

3.第三个this.foo输出undefined,因为这个IIFE(立即执行函数表达式)中的this指向window。 4.第四个self.foo输出bar,因为这个匿名函数所处的上下文中没有self,所以通过作用域链向上查找,从包含它的父函数中找到了指向myObject对象的self


 for in 中 x代表key值,所以取出的值为value。

//使用for..in循环遍历对象属性 
varperson={ 
    name: "Admin", 
    age: 21, 
    address:"shandong" 
}; 
for(var i in person){ 
    console.log(i); 
} 

执行结果:
//name 
//age 
//address 

 数组中也有for……in,相较于对象中的用法是有区别的:

var arr = ['曹操','曹植','曹丕']
for(i in arr){
console.log(i) //0 1 2
console.log(arr[i]) //曹操 曹植 曹丕
}
var obj = new Object();
obj = {
father:'曹操',
son:'曹植'
}
for(i in obj){
console.log(i) ; //代表key值 father  son
console.log(obj[i]) ; //代表vulue值 曹操  曹植
}

此题考察类型转换,三元运算符先“分清是非”,再决定今后该走哪条路,“==”运算符比较“喜欢”Number类型。(我就不严谨地这么一说,若要刨根问底,请看《JavaScript权威指南》)

下面是题目的类型转换结果:

Boolean([]); //true
Number([]); //0
Number({}); // NaN
Number(false); //0
console.log(([])?true:fasle);// => console.log((true)?true:false);
console.log([]==false?true:false); // => console.log(0==0?true:false);
console.log(({}==false)?true:false); // => console.log((NaN==0)?true:false);

“==”运算符(两个操作数的类型不相同时)

  • 如果一个值是null,另一个值是undefined,则它们相等
  • 如果一个值是数字,另一个值是字符串,先将字符串转换为数学,然后使用转换后的值进行比较。
  • 如果其中一个值是true,则将其转换为1再进行比较。如果其中的一个值是false,则将其转换为0再进行比较。
  • 如果一个值是对象,另一个值是数字或字符串,则将对象转换为原始值,再进行比较。

对象到数字的转换

  • 如果对象具有valueOf()方法,后者返回一个原始值,则JavaScript将这个原始值转换为数字(如果需要的话)并返回一个数字。
  • 否则,如果对象具有toString()方法,后者返回一个原始值,则JavaScript将其转换并返回。(对象的toString()方法返回一个字符串直接量(作者所说的原始值),JavaScript将这个字符串转换为数字类型,并返回这个数字)。
  • 否则,JavaScript抛出一个类型错误异常。

空数组转换为数字0

  • 数组继承了默认的valueOf()方法,这个方法返回一个对象而不是一个原始值,因此,数组到数学的转换则调用toString()方法。空数组转换为空字符串,空字符串转换为数字0.

两个操作数的类型不相同时

1. null==undefined

2. 字符串---->数字

3. boolean--->数字

4. 对象-------->原始值(先根据对象的valueOf()方法返回数字,没有则根据toString()方法返回字符串,再转换为数字,没有则跑出类型错误异常)

5. 数组--------->原始值 (调用toString()方法返回字符串,字符串再转成数字)

6. NaN和任何比较都是false,包括自己

例:Number([]);

// [].toString()------> ""

// Number("")---------> 0


js里面没有函数重载的概念,在其他语言中(如java)java中,可以存在同名函数,
只要传入的参数数量或者类型不同即可。在js中,定义了两个同名函数后,
后面的函数会覆盖前面定义的函数。结合这道题来说,由于函数声明提升,
所以函数声明会提前,由于存在同名函数,后面的add函数将覆盖第一个add函数
所以两次调用add()返回的值是相同的。也就是y,z都为4. 


match() 方法检索返回一个字符串匹配正则表达式的结果,匹配成功则返回数组,失败则返回null。在正则表达式中,\d表示匹配数字0-9,+表示匹配前面字符一次或者多次,\w表示匹配字母、数字或者下划线,*表示匹配前面字符0次或者多次,修饰符g表示全局匹配。由于+和*都是贪婪匹配,所以\d+匹配到75,\w*匹配到team2017,此时字符串已被全部匹配,故返回的result数组中,只有一个数组元素,即字符串75team2017,C选项正确。 


B选项,在定时器中,this指向window对象,而不是btn对象。而在定时器的同级作用域,this指代btn对象,ACD选项均是在定时器函数中使用该btn对象。 



Node 中的“微任务(microtasks)其实是一个统称,包含了两部分:

  • process.nextTick() 注册的回调 (nextTick task queue)
  • promise.then() 注册的回调 (promise task queue)

Node 在执行微任务时, 会优先执行 nextTick task queue 中的任务,执行完之后会接着执行 promise task queue 中的任务。所以如果 process.nextTick 的回调与 promise.then 的回调都处于主线程或事件循环中的同一阶段, process.nextTick 的回调要优先于 promise.then 的回调执行


运算中,+号,数字隐式转换成字符串。其余的运算符号是字符串隐式转换成数字。 


 考点:undefined隐式转换成Number类型值是啥

    1)Number(undefined) 结果是NaN,所以NaN+1 = NaN

    2)Number(null) 结果是0

    3)Number('a')结果是NaN

    4)  Number('')结果是0

    5)  Number(true)结果是1

    6)  Number(false)结果是0

    7)  Number([])结果是0

    8)  Number({})结果是NaN

D选项:函数没有返回值,默认undefined




1.getColor()  var getColor = test4399.getColor;即

var getColor = function(){
    var color = "red";
    alert(this.color);
};

执行getColor()函数时this指向的window,因为window.color为green,所以弹出green
2.test4399.getColor(),此时this指向的是test4399,test4399.color为blue,所以弹出blue


this的用法:

  • 在方法中,this 表示该方法所属的对象。
  • 如果单独使用,this 表示全局对象。
  • 在函数中,this 表示全局对象。
  • 在函数中,在严格模式下,this 是未定义的(undefined)。
  • 在事件中,this 表示接收事件的元素。
  • 类似 call() 和 apply() 方法可以将 this 引用到任何对象。

function father() {
    this.num = 935;
    this.work = ['read', 'write', 'listen'];
}
function son() {}
son.prototype = new father(); 
// son.prototype = {  num:935, work:['read','write','listen'] }

let son1 = new son(); // son1 = { }
let son2 = new son(); // son2 = { }

son1.num = 117; // son1 = { num: 117 }

son1.work.pop(); 
//son1自己没有work,去原型里找到work,并删除work里的最后一项,
//此时son.prototype = {  num:935, work:['read','write'] }

console.log(son2.num);// son2自己没有num,去原型里找,有num:935

console.log(son2.work);
//son1和son2原型是同一个,所以此时原型里的work是['read', 'write']

 原型链继承,如果属性有引用类型的,改变一个,则其他的也会跟着改变


代码回收规则如下:

1.全局变量不会被回收。

2.局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁。

3.只要被另外一个作用域所引用就不会被回收


为啥Object.definedProperty添加的属性既不能被Object.keys()遍历,也不能被for...in...遍历??? 

因为:defineProperty为对象设置属性后,该属性的描述符writable、configurable以及enumberable默认为false。

enumberable为false代表该属性不可遍历

var obj = {brand:'华为',price:1999};
Object.defineProperty(obj,'id',{value:1})
//给obj添加一个id属性,此时obj = { brand:'华为',price:1999,id:1 };
//此时id的其他属性都是false,不可被遍历,不可写,不可配置
 
Object.defineProperty(obj,'price',{configurable:false})
//configurable:false表示price不可配置,也代表不可被delete删除
 
console.log(Object.keys(obj).length); 
//因为id不可被遍历,故值为['brand','price']
 
for (var k in obj){
     console.log(obj[k]);//因为id不可被遍历,故值为 华为 1999
}
 
obj.price = 999;
delete obj['price'] //失效,因为price设置了configurable:false
console.log(obj);//obj = { brand:'华为',price:1999,id:1 };

for ...in ...可以把原型对象身上的属性遍历出来

Object.keys()不能把原型对象身上的属性遍历出来

1)属性描述对象

JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。

这个内部数据结构称为“属性描述对象”(attributes object)

2)属性描述对象的6个元属性:

  • value:设置该属性的属性值,默认值为undefined
  • writable:表示能否修改属性的值,也就是说该属性是可写的还是只读的,默认为true(可写)
  • enumerable:表示改属性是否可遍历,默认为true(可遍历)
  • configurable:表示能否通过 delete 删除属性、能否修改属性的特性,或者将属性修改为访问器属性,默认为true(可配置)
  • get:get是一个函数,表示该属性的取值函数(getter),默认为undefined
  • set:get是一个函数,表示该属性的存值函数(setter),默认为undefined

configurable  如果设为false,将阻止某些操作改写该属性,比如无法删除该属性,也不得改变该属性的属性描述对象(value属性除外


let obj = { num1: 117 } 

    把obj放在栈里,把 { num1:117} 放在堆里,让obj指向堆里的 { num1:117 }     

    let res = obj;

把res放在栈里,把res也指向堆里的 { num1:117 }     

    obj.child  =  obj  =  { num2: 935 };

重点:赋值操作先定义变量(从左到右),再进行赋值(从右到左)     

 定义变量    obj.child,给堆里的{ num1:117 }加一个child属性,得{num1:117,child:undefined}     

 定义变量    obj,之前在栈里的obj     

        


赋值    obj = { num2: 935 },把{ num2: 935 }放在堆里,把栈里的obj指向堆里的{ num2: 935 }     


赋值    obj.child = obj,把堆里的 {num1:117,child:undefined} 的child指向  {num2: 935}     

从最后一张图可看出此时:     

        obj = { num2: 935 }     

        res = { num1: 117,child:{ num2: 935 }  } 


选A; 采用in来遍历对象的属性
B是php的方法
C对象没有length, 数组才可以 


JS中的函数是非惰性求值,也就是说f(a=100)是将a=100完成计算赋值后的结果即100传入到了f函数中,传入的是值而不是逻辑,相当于f(100),同时变量a也处于函数外也即全局环境了,因此f函数里面的x一开始是传进来的100,后续被重新赋值为200. 



①中文引号,运行直接报错

②就算不报错,不是死循环,输出的#号没有换行,输出再多也只是一行

③conutine可用于for if while 语句中,表示跳出本次循环(break表示跳出循环,本次循环之后的都不执行),所以没有执行i++语句,i永远为0变成了死循环

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值