JavaScript中关于笔试题示例讲解
说明:js在程序执行开始时,会将声明提前。而申明提前的方式有两种:一种是var 声明的变量;一种是声明方式创建的函数。
另外,创建函数的方式有三种:
- 声明方式
-function 函数名 (形参列表) {
—函数体
—return 返回值
} - 赋值方式
-var 函数名=function(形参列表){
—函数体
—return 返回值
} - 用new创建,几乎不用
-var 变量名=new function(“形参1”,形参2“,…”.函数体和返回值")
强调:
(1)如果函数只是定义,而没有调用,其内部的代码是不会执行的,即使写错也不会报错!(2)任何未声明的变量,直接赋值的话,都是创建在了window中了。
(3)程序中是不允许相同的变量名存在,故后面的变量会替代前面变量的内容。
示例1:声明方式创建的函数会提前
//以下输出结果是什么
function fun(){
console.log(1);
}
fun();
function fun(){
console.log(2)
}
fun();
//答案是 2,2
解析:声明方式创建的函数会提前,两个函数function fun(){}都会提前,而最后一个输出console.log(2)的函数时唯一替代了之前的。故调用两次,输出了两个2。
示例2:赋值方式创建函数, 申明会提前但等号赋值的内容会留在在原地
var fun=function(){console.log(1)};
fun();
var fun=function(){console.log(2)};
fun();
//打印输出的结果是1 和2
程序执行相当于:
首先声明提前:
var fun
再开始执行程序:
fun=function(){console.log(1)};
fun(); //1
fun=function(){console.log(2)};
fun(); //2
示例3:函数名也是变量
function fun(){console.log(1)}
fun(); //? 2
function fun(){console.log(2)};
fun(); //? 2
var fun=100;
fun(); //? 报错:fun is not a function
示例4:定义一个函数,可计算任意个数字的和
function add(){
sum=0;
for(var i=0;i<arguments.length;i++){
sum+=arguments[i]
}
return sum;
}
console.log(
add(1,2,3), // 6
add(1,2,3,4,5), //15
add(1,2,3,4,5,6,7) //28
)
解析:重载是多个同名函数,不同形参列表,在调用时,可根据实参列表的不同,动态选择匹配参数的函数执行。 js中借助于arguments 对象来实现重载。arguments是每个函数内自带的,专门接受所有传入函数的实参值列表的类数组对象。
即:arguments=[实参1,实参2,实参3…]
示例5:闭包
function fun(){
var n=999;
nAdd=function(){n++};
return function(){console.log(n)}
}
console.log(fun()); // function(){console.log(n)}
var getN=fun();
getN(); //999
nAdd();
getN(); //1000
//任意函数没被调用的话,它里面的结果就不会被执行!!!!
解析:强行给一个未声明的变量赋值,结果会自动在全局创建该变量,不会报错;
所以fun 生了两个孩子:
1.nAdd但是他被创建到了全局window里,因为他是fun生的,所以fun的变量他可以用,故nAdd();执行的结果是n++,使n=1000.
2.function
示例6:循环退出
function fun(){
for(var i=0,arr=[];i<3;i++){
arr[i]=function(){console.log(i)}
}
return arr;
}
var funs=fun();
funs[0](); //3
funs[1](); //3
funs[2](); //3
解析:i=3时,才退出循环
程序执行:
arr=[function(){console.log(i)},function(){console.log(i)},function(){console.log(i)}];
|| || ||
funs=arr; funs[0] funs[1] funs[2]
i=3;
故三个结果都是输出3!
示例7:局部变量和全局变量
function change(o){
o.name="西西";
o={};
o.name="小红";
}
var o={name:"小静",age:11}
change(o);
console.log(o) // {name: "西西", age: 11}
function change( ){
o.name="西西";
o={};
o.name="小红";
}
var o={name:"小静",age:11}
change(o);
console.log(o) // {name: "小红"}
function change(){
o.name="西西";
o.name="小红";
}
var o={name:"小静",age:11}
change(o);
console.log(o) // {name: "小红", age: 11}
示例8:求数组中最大的值
问题:
var arr=[1,5,122,88,0.2,9];
求其最大值
//1.es6拓展运算符...
var max=Math.max(...arr)
console.log(max);
//2.es5 apply(与方法1原理相同)
var max=Math.max.apply(null,arr);
console.log(max);
//3.for循环
var max=arr[0];
for(var i=0;i<arr.length-1;i++){
max=max<arr[i+1]?arr[i+1]:max
}
console.log(max);
//4.数组sort()
arr.sort((a,b) => a-b);//arr 从小到大排序
var max=arr[arr.length-1]
console.log(max);
arr.sort((a,b) => b-a);//arr 从大到小排序
var max=arr[0]
console.log(max);
//5.数组reduce
arr.reduce((a, b) => {
return a > b ? a : b}
)
示例9:获取地址栏的查询参数,并转化为js对象
var a=“www.qq.com?name=jack&age=18&id=100&key=abc”
转化为对象格式
- var url=location.href; //取得整个地址栏
- var url = location.search; //获取url中"?"符后的字串
//方法一:原生数组分割法
var str="www.qq.com?name=jack&age=18&id=100&key=abc"
var str=str.split("?")[1];
//console.log(str);//name=jack&age=18&id=100&key=abc
var str=str.split("&");
//console.log(str);//["name=jack", "age=18", "id=100", "key=abc"]
var newStr={};
for (var i = 0; i < str.length; i++) {
newStr[str[i].split("=")[0]] = str[i].split("=")[1]
}
console.log(newStr);//{name: "jack", age: "18", id: "100", key: "abc"}
//方法二:正则表达式
function GetQueryString(name){
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
// 调用方法
alert(GetQueryString("参数名1"));
console.log(GetQueryString("参数名2"));
//方法三:字符串查询
function GetRequest() {
var url = location.search; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for(var i = 0; i < strs.length; i ++) {
theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);
}
}
return theRequest;
}
// 调用方法
var Request = new Object();
Request = GetRequest();
var 参数1,参数2,参数3,参数N;
参数1 = Request['参数1'];
参数2 = Request['参数2'];
扩展:部分属性有多个属性值的情况
//location.search
var search="?uname=dingding&upwd=123456&favs=swimming&favs=running&favs=basketball";
function search2Obj(str){
//创建新的空对象
var obj={};
//去掉str开头的?
str=str.slice(1);
//"uname=dingding&upwd=123456&favs=swimming&favs=running&favs=basketball"
//按&切割str
var arr=str.split("&");
//["uname=dingding","upwd=123456","favs=swimming","favs=running","favs=basketball"]
//遍历arr中每个子字符串
for(var s of arr){
//按=切割每个子字符串,然后,将切割后第一部分保存在变量key中,将切割后第二部分保存在变量value中
var [key,value]=s.split("=");
//如果obj中不包含key为下标的属性
if(obj[key]===undefined){
//就前行给obj添加key为下标的属性,并赋值
obj[key]=value;
}else{//否则,如果obj中已包含key为下标的属性
//就取出obj中key属性的值,和新值value拼成一个新数组,再放回obj中key属性保存
obj[key]=[].concat(obj[key],value);
}
}
return obj;//返回obj
}
var obj=search2Obj(search);
console.log(obj);
/*obj:{
uname:dingding,
upwd:123456,
favs:[swimming, running, basketball]
}*/
示例10:数组去重
问题:arr=[1,3,4,2,4,4,5];
输出为arr=[1,3,4,2,5];
- ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 new Set(参数) ,参数可以是数组。返回的是对象形式!!!Array.from方法可以将 Set 结构转为数组
// 方法一:se6 set()方法
arr=new Set(arr);//{1,3,4,2,5}
arr=Array.from(arr); //[1,3,4,2,5]
console.log(arr);
//方法二:主要利用高阶函数 filter()和indexOf() 进行去重
arr2=[1,2,'2',5,7,5,2];
function unique(array) {
var res = array.filter((item, index, array) => {
return array.indexOf(item) === index
})
return res
}
unique(arr2);
//方法三:indexOf() 返回 某个指定字符串在字符串中首次出现的位置, 如果没有匹配到返回 -1
arr=[1,2,'2',5,7,5,2];
function unique2(array) {
var res = []
for (let i = 0; i < arr.length; i++) {
var current = arr[i]
if (res.indexOf(current) === -1) {
res.push(arr[i]);
}
}
return console.log(res)
}
unique2(arr);
//方法四:map()方法 一个Map对象在迭代时会根据对象中元素的插入顺序来进行 —
//一个 for...of循环在每次迭代后会返回一个形式为[key,value]的数组。
arr=[1,2,'2',5,7,5,2];
function unique3(arr) {
const temp = new Map()
return arr.filter((a) => !temp.has(a) && temp.set(a, 1))
}
console.log(unique3(arr))
//方法五:双重循环
var arr = [4, 4, 2, "2", 1]
function unique1(array) {
var res = []
for (let i = 0; i < arr.length; i++) {
for (var j = 0; j < res.length; j++) {
if (arr[i] === res[j]) {
break;
}
}
if (j === res.length) {
res.push(arr[i])
}
}
return res
}
console.log('unique1', unique1(arr))
示例11:复制一个新地址的数组,两个地址互不干扰
问题:arr=[1,2,3,5,6];
创建一个arr1=arr,但是形成了两个引用地址,两个数组变化但互不干扰
即console.log(arr1==arr);为false
//slice()方法;
var arr=[1,2,3,5,6];
var arr1=arr.slice();
console.log(arr1==arr);
//map()方法
var arr=[1,2,3,5,6];
var arr1=arr.map((elem)=>{
return elem
})
console.log(arr1==arr);
//set()方法
var arr=[1,2,3,5,6];
var arr1=Array.from(new Set(arr));
console.log(arr1==arr);
示例12:统计一个字符串中每个字符出现的个数
//方法一:
var str="helloworld";
var arr=str.split("");//需要将字符串转化为数组,才能用数组家的方法
var result=arr.reduce(
function(prev,elem){
//prev:{h:1, e:1, l:2, o:1, w:1..}
// elem:"o"
//如果prev中没有这个字母的属性
if(prev[elem]===undefined){
prev[ elem ]=1
//prev[ "o" ]=1
}else{//否则,就+1
prev[elem]+=1
//prev["o" ]
// 1 +=1
// 2
}
//prev:{h:1, e:1, l:2, o:2, w:1}
return prev
},
{}//prev
)
console.log(result);//{h: 1, e: 1, l: 3, o: 2, w: 1,r:1,d: 1}
//方法二:ES6中 for(of)方法, 遍历字符串、agruments,结果可自动转为数组
var result={};
var str="helloword";
for(var char of str){
if(result[char]===undefined){
result[char]=1
}else{
result[char]+=1;
}
}
console.log(result);//{h: 1, e: 1, l: 3, o: 2, w: 1,r:1,d: 1}
示例13:从33个红球中随机挑选,按从大到小的排列
function getRed(){
reds=[];
while(reds.length<6){
var red=Math.ceil(Math.random()*33);
if(reds.indexOf(red)==-1){
reds.push(red);
}
}
reds.sort((a,b)=>{a-b});
console.log(reds);
}
getRed();
示例14:利用map()方法,将数组的内容动态生成页面显示
<!--html代码-->
<ul id="ulScores">
<!--
<li>85</li>
<li>72</li>
<li>90</li>
<li>95</li>
-->
</ul>
//js中的代码
var scores=[85,72,90,95];
//1. 遍历每个成绩,将每个成绩变为一个<li></li>元素,放入新数组中
var newArr=scores.map(
function(elem){
return `<li>${elem}</li>`
}
)
console.log(newArr);
//2. 将新数组无缝拼接为字符串
var html=newArr.join("");
console.log(html);
//3. 将字符串赋值给ul的innerHTML
//补: 所有id属性,自动会变为全局变量。不用找,可直接使用!
ulScores.innerHTML=html;
//代码简写: /*ulScores.innerHTML=scores.map(
function(elem){
return `<li>${elem}</li>`
}
).join("");*/
示例15:复制创建新地址的对象,两个地址互不影响 转为数组见示例11
请将变量data 复制给变量newData且不影响变量data。
//方法一:
var data={a:1,b:2,c:3}
var newData={
...data
}
console.log(newData)
//方法二:
newDate=JSON.parse(JSON.stringify(data));
console.log(newData)
示例16:多种方法换取两个变量的值,但不能申明第三个变量。
问题:var a=3,b=6;
是最后打印结果是a=6,b=3
//方法一:
var a=3,b=6;
a+=b,b=a-b,a-=b;
console.log(a,b)
//方法二:
a^=b,b^=a,a^=b;
//方法三:
a=[b,b=a][0];
//方法四:
[a,b]=[b,a];
示例17:冒泡排序
从小到大的排序
//手写js方法:
var arr=[3,1,1,4,88,99,234,56]
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr.length;j++){
if(arr[j]>arr[j+1]){
var max=arr[j];
arr[j]=arr[j+1];
arr[j+1]=max
}
}
}
console.log(arr);
//sort()
arr.sort((a,b)=>{ return a-b})
console.log(arr)