21-40
21.闭包面试题
答案是This Window 。this以函数形式调用时,this指向的是window。
答案是My Object。
答案是:
- undefined,0,0,0;
- undefined,0,1,2;
- undefined,0,1,1
22.数据类型存储以及堆栈内存是什么?堆(heap)和栈(stack)有什么区别存储机制?
- 基本数据类型:直接存储在栈内存中,占据空间小,大小固定,属于被频繁使用的数据。指的是保存在栈内存中的简单数据段;number string 布尔
- 引用数据类型:同时存储在栈内存与堆内存中,占据空间大,大小不固定。
- 引用数据:类型将指针存在栈中,将值存在堆中。 当我们把对象值赋值给另外一个变量时,复制的是对象的指针,指向同一块内存地址,意思是,变量中保存的实际上只是一个指针,这个指针指向内存堆中实际的值
- 栈:是一种连续存储的数据结构,具有先进后出后进先出的性质。
- 通常的操作有入栈(压栈),出栈和栈顶元素。
- 堆:是一种非连续的树形储存数据结构,具有队列优先,先进先出;
- 每个节点有一个值,整棵树是经过排序的。特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。常用来实现优先队列,存取随意。
23.判断
undefined == null; // true
1 == true; // true
2 == true; // false
0 == false; // true
0 == ''; // true
NaN == NaN; // false,NaN与任何值都不相等,包括NaN自身。故为false
[] == false; // true
[] == ![]; // true
对于原始值直接调用Number()
对于对象先调用valueOf()方法
- 如果获取的不是原始值,对象.toString()
- 最后再Number()
valueOf()
toString()
24.已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”
function toHump(foo){
const fooArray=foo.split("-")
for(let i=1;i<fooArray.length;i++){
const initial =fooArray[i].at(0)
fooArray[i]=fooArray[i].replace(initial,initial.toUpperCase())
}
return fooArray.join("")
}
const result=toHump("get-element-by-id")
console.log(result)
25.输出今天的日期,以YYYY-MM-DD的方式
function showDate(){
let date=new Date()
let year=date.getFullYear()
let month=date.getMonth()+1
if(month<=9){
month="0"+month
}
let day=date.getDate()
if(day<=9){
day="0"+day
}
return year+"-"+month+"-"+day
}
console.log(showDate())
25.将字符串中的{$id}替换成10,{$name}替换成Tony (使用正则表达式)
let str="<tr><td>{$id}</td><td>{$name}</td></tr>"
let reg=/{\$id}/
str=str.replace(reg,"10")
reg=/{\$name}/
str=str.replace(reg,"Tom")
console.log(str)
26.foo = foo||bar,这行代码是什么意思?为什么要这样写?
如果foo存在,值不变,否则把bar的值赋给foo。
短路表达式:作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,
只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。
27.看下列代码,将会输出什么?
var foo = 1;
(function(){
console.log(foo);//undefined
var foo = 2;
console.log(foo);//2
})()
28.为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, \进行转义
function excapeHtml(str) {
const reg = /["<>&]{1}/g
let strAray=str.split("")
//转换字符
function replaceC(s) {
let result
switch (s) {
case "<":
result = "<"
break
case ">":
result = ">"
break
case "\"":
result = """
break
default: result = "&"
}
return result
}
let match = reg.exec(str)
while (match) {
strAray[match.index]=replaceC(match[0])
match = reg.exec(str)
}
return strAray.join("")
}
console.log(excapeHtml('12&<&&>&""1234'))//12&<&&>&""1234
29.用js实现随机选取10–100之间的10个数字,存入一个数组,并排序。
const arr=[]
for(let i=0;i<10;i++){
arr.push(Math.floor(Math.random()*91+10))//[10,101)
}
arr.sort((a,b)=>a-b)
console.log(arr)
30.把两个数组合并,并删除第二个元素
const arr=["啊伟","啊强","啊芳"]
const arr1=[1,2,3,9,22,42,11]
const newArr= arr.concat(arr1)
newArr.splice(1,1)
console.log(newArr)
31.解析查询字符串
//有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,
//请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),
//将其按key-value形式返回到一个json结构中,如{a:'1', b:'2', c:'', d:'xxx', e:undefined}。
function getValue(url){
const getStr=url.slice(url.indexOf("?")+1)
const arr=getStr.split("&")
const json={}
for(let s of arr){
const sArr=s.split("=")
json[sArr[0]]=sArr[1]
}
return json
}
const url="http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e"
getValue(url)
32.以下两个变量a和b,a+b的哪个结果是NaN?
- var a=undefined ; b=NaN// NaN
- var a='123'; b=NaN // "123NaN"
- var a=undefined , b =NaN// NaN
- var a=NaN , b='undefined'// "NaNundefined"
解析:
- 任意数值加上NaN都是NaN
- String(Number)="Number",NaN=>"NaN"
33.写一个function,清除字符串前后的空格
function mytrim(str){
return str.replace(/^\s*/,"").replace(/\s*$/,"")
}
console.log(mytrim(" hello world "))
34.正则表达式构造函数与正则表达字面量有什么不同?匹配邮箱的正则表达式?
- 采用构造函数需要接收两个字符串参数(正则表达式和匹配模式),由于是字符串的形式需要对转义字符进行转义,表示它是个普通字符
- 采用字面量的形式(/正则表达式/匹配规则)则不用转义,书写简单
- 但是第一种方式可以动态生成正则表达式,第二种是写死的
- 邮箱的正则表达式:
- 邮箱的规则是:名称@域名。
- 邮箱名称的规则:由英文字母、数字、下划线组成。
- 邮箱域名的规则:由英文字母、数字、下划线、"."组成。一般常见的域名都是一级域名,例如yqq@qq.com,还有很多其他的多级域名,例如yqq@ywx.163.com
const reg=/^\w+@\w+(\.\w+)+$/
const email="2841320560@qq.com"
console.log(reg.test(email))
35.写出函数DateDemo的返回结果,系统时间假定为今天
function DateDemo() {
var d, s = "今天日期是:";
d = new Date();
s += d.getMonth() + 1 + "/";
s += d.getDate() + "/";
s += d.getFullYear();
return s;
}
console.log(DateDemo());
36.写出简单描述html标签(不带属性)的正则表达式,并将以下字符串中的html标签去除掉
function eliminateHtml(str){
const reg=/<\/?[a-z]+>/g
str=str.replace(reg,"")
console.log(str);
}
let str="<div>这里是div<p>里面的段落</p></div>"
eliminateHtml(str)
37.Javascript如何实现继承?
- 构造继承法
- 构造继承法是使用了function对象的call()和apply()方法
- call的第一个参数用作this对象,其余参数是传给函数的参数.
- apply用法基本与call相同,不同的是apply方法只有两个参数,第一个用作this对象,第二个参数是要传给函数的参数数组
function A(sName){
this.name = sName;
this.sayName = function(){
alert(this.name);
}
}
function B(sName,sAge){
A.call(this,sName);
this.age = sAge;
this.sayAge = function(){
alert(this.age);
}
console.log(sName);//啊伟
console.log(sayName);//函数体
}
B("啊伟",18)- 这样B内部调用了A的构造函数,从而实现了对A的继承
- 用prototype定义的属性和方法时不能用这种方法继承的
- 原型链(子原型=父的实例)
function A(){}
A.prototype.color = "pink";
A.prototype.sayColor = function(){
alert(this.color);
}
function B(){}
B.prototype = new A();
B.prototype.name = "";
B.prototype.sayName = function(){
alert(this.name);
}