JavaScript专项练习(持续更新)

361 阅读7分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

此帖为我在牛客网刷JavaScript专项练习时出错或不熟练部分的总结。

2-25

JavaScript中定义var a = "40", var b = 7,则执行a%b会得到?

在进行运算时,+号会将数字隐式转换为字符串;其余的运算符号是将字符串隐式转换为数字。

正则表达式相关符号对应的意义。举例。

^:匹配字符串的开头; $:匹配字符串的结尾;

  • :出现零次到多次; +:出现一次或多次; ?:出现零次或一次; .:除了\n以外的任意字符; \w:表示字母、数字、下划线; \W:表示除了字母、数字、下划线的字符; i:忽略大小写; \1:对分组进行捕获; {n}:出现n次; {n,m}:出现n到m次; {n,}:出现n到多次。
下面代码输出结果为
var str1=newRegExp("e");
document.write(str1.exec("hello"));

RegExp对象的主要方法是exc(),该方法是专门为捕获组而设计的。exec()接收一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。 --来源JavaScript高级程序设计

image.png

JavaScript RegExp对象有3个方法:test()、exec()、complie()

  • test():用来检测一个字符串是否匹配某个正则表达式,如果匹配成功返回true,否则返回false;
  • exec():用来检索字符串种与正则表达式匹配的值。exec()方法返回一个数组,其中存放匹配的结果;
  • compile():可以在脚本执行过程中编译正则表达式,也可以改变已有表达式。
JavaScript的call方法和apply方法。
  • 作用:两者的作用相同,都是:在特定的作用域调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域;
  • 区别:接收参数的方式不同:对于call(),接收的参数个数不定,第一个参数是运行函数的作用域,其余参数都是直接传递给函数,即传递给函数的参数必须逐个列举出来;对于apply(),固定是两个参数,第一个参数依旧是运行函数的作用域,但是,另一个参数是参数数组,可以是array实例或是arguments对象。
下面的代码将返回:
Number(null);

将返回0。 下面的情况都会转换为0:

  • Number();
  • Number(0);
  • Number("");
  • Number("0");
  • Number(false);
  • Number(null);
  • Number([]);
  • Number([0]).

下面的情况都会转换为NaN:

  • Number(undefined);
  • parseInt("");
  • parseInt(null);
  • parsreInt(undefined).
(箭头函数)下面的js代码的输出结果会是什么?
var a = "w";
let obj = {
  a:"o",
  print:function(){
    console.log(this.a);
  },
  print2:() => {
    console.log(this.a);
  }
}
let p = obj.print();
pet p2 = obj.print2();
obj.print();
obj.print2();
p();
p2();

函数的扩展 - ECMAScript6入门

普通函数中,this永远指向调用者的作用域;箭头函数中,this指向定义时的上下文,即此时的this即使定义时上层作用域中的this。

image.png

同理,下一题也是涉及JavaScript中的this指向问题。

以下代码,在浏览器中执行的结果是
var A = {n:4399};
var B = function(){this.n = 9999};
var C = function(){var n = 8888};
B.prototype = A;
C.prototype = A;
var b = new B();
var c = new C();
A.n++;
console.log(b.n);
console.log(c.n);

结果是:9999 4400

但是这里要注意的是,b里面是有n属性,但是c是没有n属性,所以c需要向上查找,找到原型(也也就是prototype)中是否有n属性。

请问以下js代码的输出是?
function father() {
  this.num = 935;
  this.work = ['read', 'write', 'listen'];
}
function son() {}
son.prototype = new father();
let son1 = new son();
let son2 = new son();
son1.num = 117;
son1.work.pop();
console.log(son2.num);
console.log(son2.work);

输出结果为:935、['read','write','listen']
分析:这里又涉及到了引用类型和基本数据类型的区别。

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 = {}
  console.log(son2);
  son1.num = 117; // son1 = {num:117}
  son1.work.pop(); // son1没有work,所以去原型上找,删除最后一项
  // son.prototype = {num:935;work:['read','write']}
  console.log(son2.num); // 去原型上找
  console.log(son2.work); //去原型上找
下面的代码存在几个变量没有被回收?
var i = 1;
var i = 2;
var add = function() {
    var i = 0;
    return function()
{
        i++;
        console.log(i);
    }
}();
add();

代码回收规则

  • 全局变量不会被回收;
  • 局部变量会被回收,即函数一旦运行完毕,函数内部的东西都会被销毁;
  • (闭包引用的局部变量)只要被另一个作用域引用就不会被回收。
在JavaScript中,哪些是原始值(primitive value)?

ECMAScript中,变量可以存放两种类型的值,即原始值引用值

  • 原始值:存储在栈中的简单数据段,即他们的值直接存储在变量访问的位置;
  • 引用值:存储在堆中的对象,即,存储在变量处的值时一个指针,指向存储对象内存处。 es6中新增一种原始数据类型:symbol

js的原始数据类型有6种:undefinednullBooleanstringsymbol(es6)、number

下列代码输出为?
var person={fname:"John",lname:"Doe",age:25};
var txt="";
for (x in person)
{
  txt=txt + person[x];
}
alert(txt);

输出为:JohnDoe25.

image.png for.....in在数组和对象中的用法有很大的区别:

  • 数组中:
var arr = ["熊大", "熊二", "光头强"];
  for (i in arr) {
    console.log(i);
    console.log(arr[i]);
}

image.png

  • 对象:
var obj = new Object();
obj = {
  brother: "熊大",
  bro2: "熊二"
};
for (i in obj) {
  console.log(i);
  console.log(obj[i]);
}

image.png

image.png

执行下面的程序,输出结果为:
function fn(o,val){
  o.b = 1;
  val = 1;
}
var obj = {b:0};
var num = 0;
fn(obj,num);
console.log(obj,num);

结果为:{b:1},0

此题主要考察从一个变量向另一个变量复制基本类型的值和引用类型的值时的不同:

  • 基本数据类型:存储在栈中的简单数据段;
  • 引用数据类型:存储在堆中的对象,存储在栈中的值是一个指针,指向存储对象的内存地址。

image.png

2.26

请问以下的js代码输出结果是什么?
console.log(typeof ''.prototype);
console.log(typeof ''.__proto__); 
console.log(typeof ''.__proto__ === typeof ''.prototype);

(考察js原型!!)

1)函数(或构造函数)才有prototype(原型,是一个对象)
如:String、number、Boolean、array、object image.png 2)其他任何通过构造函数实例化出来的对象都有_proto_(隐式原型,也是对象)

image.png (自动提示都没有prototype)

image.png

3)实例化对象的_proto_就是构造函数的prototype

image.png

哪些属于JavaScript的typeof运算符的结果?

image.png

image.png

执行以下代码,5秒后输出的结果为?
for(var i = 0; i < 5; i++){
    setTimeout(function(){
        console.log(i);
    }, 1000 * i);
}

这个题涉及异步、作用域。注意。这里的for循环内声明变量用的是var,如果换成let后,结果又不一样了。()因为let在循环条件的时候定义,而不是在外部定义,则每一次循环let都会生成一个块级作用域保存当前的值)
首先,settimeout是一个异步任务,所以就要先完成for同步任务,直到循环执行完毕才会调用settimeout这个异步任务。循环完毕后i=5,跳出循环,此时i=5.

以下代码执行后,num的值是?
var foo=function(x,y){
  return x-y;
}
function foo(x,y){
  return x+y;
}
var num=foo(1,2);

js变量提升与函数提升的详细过程 编译顺序为:

// 函数声明提升
function foo(x,y){
  return x + y;
}
// 变量声明提升
var foo;
var num;
// 赋值 不提升
foo = function(x,y){
  return x - y;
}

(函数提升在变量提升之前,所以函数提升在最前面) 所以,最后,foo返回的是x - y

执行以下程序,输出结果为
var a = 100;
function a(){
  var a = 200;
  console.log(a);
}
a();

顺序:

function a(){
  var a;
  a = 200;
  console.log(a);
};
var a;
a = 200; // 此时啊已不再是函数,而是number类型的数字
a(); // a类型不再是函数,所以类型有错
哪些方法可以在同一个窗口下检测一个js对象是数组类型?
  • Array.isArray():array自身方法;
  • instanceof:返回一个布尔值,表示对象是否为某个构造函数的实例; Array instanceOf Array
  • Object.prototype.toString.call():返回参数的类型字符串

image.png