7-12
(1) 找出元素item在给定数组arr中的位置:
function indexOf(arr, item){
var flag = -1; //设置标记
for(var key in arr){ //遍历数组
if(arr[key] == item){ //找到查找元素,将标记位设为对应元素下标
flag = key;
}
}
return flag; //返回下标
}
function indexOf(arr, item) {
if (Array.prototype.indexOf){ //先判断数组原型链上是否存在indexOf()方法,存在直接调用
return arr.indexOf(item);
} else { //不存在则遍历数组,进行判断
for (var i = 0; i < arr.length; i++){
if (arr[i] === item){ //找到,返回下标
return i;
}
}
}
return -1; //没找到返回-1
}
var arr=[1,5,6,7,8];
console.log(indexOf(arr,8));
(2) 计算给定数组arr中所有元素的总和
function sum(arr){
var sum = 0;
for(var key in arr){ //遍历相加
sum += arr[key];
}
return sum; //返回
}
function sum(arr) { //递归
var len = arr.length;
if(len == 0){ //条件判断,数组为空的情况
return 0;
} else if (len == 1){ //数组为一个元素的情况
return arr[0];
} else { //数组元素第一个元素剔除后,后面元素看成一个新的数组,递归调用sum()
return arr[0] + sum(arr.slice(1));
}
}
console.log(sum([1,2,3]));
function sum(arr) {
return arr.reduce(function(prev, curr, idx, arr){ //reduce()方法迭代数组里的所有项,函数返回的任何值都会作为第一个参数自动传给下一项
return prev + curr;
});
}
console.log(sum([1,2,3]));
function sum(arr) {
var s = 0;
arr.forEach(function(val, idx, arr) { //对数组的每一项运行给定函数,无返回值
s += val;
}, 0);
return s;
};
console.log(sum([1,2,3]));
function sum(arr) {
var s = 0;
arr.map(function(val, idx, arr) { //对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
s += val;
}, 0);
return s;
};
console.log(sum([1,2,3]));
(3) 移除数组arr中的所有值与item相等的元素,不要直接修改数组arr,结果返回新年的数组
function remove(arr,item){
var newArr = []; //定义新数组
for(var key in arr){
if(arr[key]!=item){ //遍历原数组,将不相等的元素oush进新数组
newArr.push(arr[key]);
}
}
return newArr;
}
7-13
(1) 在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组
function append(arr, item) {
var newArr=[];
newArr=arr.slice(0); //slice()从已有数组中返回指定的元素,将原数组全部复制到新数组中
newArr.push(item); //在新数组末尾push一个元素
return newArr; //返回新数组
}
(2) 删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组
function curtail(arr) {
var newArr=[];
newArr=arr.slice(0); //复制原数组到新数组
newArr.shift(); //利用shift()方法将新数组的第一个元素删除
return newArr;
}
function curtail(arr) {
return arr.slice(1); //从原数组的第二个元素开始选取,相当于踢掉第一个元素
}
console.log(curtail([1,3,5,6]));
function curtail(arr) {
return arr.filter(function(v,i) { //利用filter过滤掉不符合条件的元素
return i!==0;
});
}
console.log(curtail([1,3,5,6]))
(3)在数组 arr 的 index处添加元素 item。不要直接修改数组 arr,结果返回新的数组
function insert(arr, item, index) {
var newArr=[];
newArr=arr.slice(0);
newArr.splice(index,0,item);
return newArr;
}
7-14
(1)找出数组中重复的元素
function duplicates(arr) {
var mp=[];
var arrNew=[];
for(var key in arr){ //判断元素是否存在于mp中,不存在,则放进去,位置处置1,存在将其加1
if(mp[arr[key]]){
mp[arr[key]]++;
}else{
mp[arr[key]]=1;
}
}
for(var key in mp){ //遍历mp,将其中键值对的值大于1的元素push进新数组
if(mp[key]>1){
arrNew.push(key);
}
}
return arrNew; //返回新数组
}
(2)时间格式化输出
function formatDate(t,str){
var obj = {
yyyy:t.getFullYear(),
yy:(""+ t.getFullYear()).slice(-2),
M:t.getMonth()+1,
MM:("0"+ (t.getMonth()+1)).slice(-2),
d:t.getDate(),
dd:("0" + t.getDate()).slice(-2),
H:t.getHours(),
HH:("0" + t.getHours()).slice(-2),
h:t.getHours() % 12,
hh:("0"+t.getHours() % 12).slice(-2),
m:t.getMinutes(),
mm:("0" + t.getMinutes()).slice(-2),
s:t.getSeconds(),
ss:("0" + t.getSeconds()).slice(-2),
w:['日', '一', '二', '三', '四', '五', '六'][t.getDay()]
};
return str.replace(/([a-z]+)/ig,function($1){return obj[$1]});
}
function fun(str){ //另外的例子
var obj ={
xs:12,
y:23,
z:34
};
return str.replace(/\w+/ig,function($1){return obj[$1]})
}
console.log(fun("xs-y-z"))
(3)斐波那契数列
function fibonacci(n) {
var arr = [ 1, 1 ];
for( var i = 2; i < n; i++ ){ //递归
arr[i] = arr[i-1] + arr[i-2];
}
return arr[n-1];
}
7-15
(1)颜色rgb转换为十六进制表示
function rgb2hex(sRGB) { //rgb转换为十六进制 (通过率50%)
var r = sRGB.split('(')
if( r[0] != "rgb"){
return sRGB
}
var l = r[1].split(')')
if(l[1].length != 0){
return sRGB
}
var s = l[0].split(',')
return '#'+parseInt(s[0]).toString(16)+parseInt(s[1]).toString(16)+parseInt(s[2]).toString(16)
}
console.log(rgb2hex('rgb(55, 255, 255)'))
function rgb2hex(sRGB) {
var regexp=/rgb\((\d+),\s*(\d+),\s*(\d+)\)/;
var ret=sRGB.match(regexp);
if(!ret){
return sRGB;
}else{
var str='#';
for(var i=1;i<=3;i++){
var m=parseInt(ret[i]);
if(m<=255&&m>=0){
str+=(m<16?'0'+m.toString(16):m.toString(16));
}else{
return sRGB;
}
}
return str;
}
}
(2) css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能 1. 以 - 为分隔符,将第二个起的非空单词首字母转为大写 2. -webkit-border-image 转换后的结果为 webkitBorderImage
function cssStyle2DomStyle(sName) {
var strArr=sName.split("-");
var i = 1
if(strArr[0].length == 0 ){
i = 2;
}
for(len=strArr.length;i<len;i++){
var a = strArr[i][0]
if(a>='a' && a <='z'){
var aU = a.toUpperCase()
strArr[i] = strArr[i].replace(a,aU)
}
}
return strArr.join("");
}
console.log(cssStyle2DomStyle('-webkit-border-image'))
function cssStyle2DomStyle(sName) {
return sName.replace(/(?!^)\-(\w)(\w+)/g, function(a, b, c){
return b.toUpperCase() + c.toLowerCase();
}).replace(/^\-/, '');
}
function cssStyle2DomStyle(sName) {
var arr = sName.split('');
//判断第一个是不是 '-',是的话就删除
if(arr.indexOf('-') == 0)
arr.splice(0,1);
//处理剩余的'-'
for(var i=0; i<arr.length; i++){
if(arr[i] == '-'){
arr.splice(i,1);
arr[i] = arr[i].toUpperCase();
}
}
return arr.join('');
}
(3)为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组
function square(arr) {
var newArr = arr.slice(0);
var mpResult=newArr.map(function(item,index,newArr){
return item * item ;
});
return mpResult;
}
function square(arr) {
var a = []; //声明一个新的数组存放结果
arr.forEach(function(e){
a.push(e*e); //将arr中的每一个元素求平方后,加入到a数组中
});
return a;
}
7-16
(1)全局变量:
function globals() {
var myObject = {
name : 'Jory'
};
return myObject;
}
(2)正确parseInt()用法
function parse2Int(num) {
var sum = ""
for(var i = 0; i < num.length && (num[i]>='0' && num[i]<='9'); i++){
sum = sum+num[i]
}
num = sum
return parseInt(num);
}
function parse2Int(num)
{
return parseInt(num,10);
}
(3)实现一个打点计时器,要求
1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作
3、第一个数需要立即输出
function count(start, end) {
//立即输出第一个值
console.log(start++);
var timer = setInterval(function(){
if(start <= end){
console.log(start++);
}else{
clearInterval(timer);
}
},100);
//返回一个对象
return {
cancel : function(){
clearInterval(timer);
}
};
}
7-17
(1)将函数 fn 的执行上下文改为obj 对象
function speak(fn, obj) {
return fn.call(obj);
}
(2) 实现 fizzBuzz 函数,参数 num 与返回值的关系如下:
1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz
2、如果 num 能被 3 整除,返回字符串 fizz
3、如果 num 能被 5 整除,返回字符串 buzz
4、如果参数为空或者不是 Number 类型,返回 false
5、其余情况,返回参数 num
function fizzBuzz(num) {
if(num=="" || isNaN(num) ){ //参数为空或非Number
return false
}
if(num%15 == 0){
return "fizzbuzz"
}else if(num%3 == 0){
return "fizz"
}else if(num%5==0){
return "buzz"
}else{
return num
}
}
(3)实现函数 functionFunction,调用之后满足如下条件:
1、返回值为一个函数 f
2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', '
3、所有函数的参数数量为 1,且均为 String 类型
function functionFunction(str) {
return f=function(str1){
return str + ', ' + str1;
}
}
7-18
(1) 二次封装函数:
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
function partial(fn, str1, str2) {
return function result(arg){ //sxt
return fn.apply(this, [str1, str2, arg]); //利用apply改变上下文
}
}
(2) 函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。
function useArguments() {
var sum=0;
if(arguments.length < 1){
return 0;
}else if(arguments.length == 1){
return arguments[0];
}else{
for(var i=0; i<arguments.length; i++){
sum += arguments[i];
}
return sum;
}
}
function useArguments() { //谁知道这种方法出在哪里???
var sum=0;
if(arguments.length < 1){
return 0;
}else if(arguments.length == 1){
return arguments[0];
}else{
sum = arguments.reduce(function(prev, cur, index, array){ //利用reduce()进行归并求取
return prev + cur;
});
return sum;
}
}
(3) 二次封装函数
实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result
2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn) {
//先获取p函数第一个参数之后的全部参数
var args = Array.prototype.slice.call(arguments,1);
var result = function(){ //声明result函数
//使用concat合并两个或多个数组中的元素
return fn.apply(null, args.concat([].slice.call(arguments)));
}
return result;
}
7-19
(1) 柯里化:已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
function curryIt(fn) { //sxt
var args=Array.prototype.slice.call(arguments); //伪数组
var a=function(arga){
return b=function(argb){
return c=function(argc){
return fn.call(null,arga,argb,argc);
}
}
}
return a;
}
(2)且运算:返回参数 a 和 b 的逻辑且运算结果
function and(a, b) {
var c = a && b; //sxt
return c;
}
或
function and(a, b) {
return a*b!=0?true:false
}
或
function and(a, b) {
//var c = a && b; //sxt
//return c;
if(a == 0 ){
return false
}
if(b == 0){
return false
}
return true
}
(3)二进制转换,给定二进制字符串,将其换算成对应的十进制数字
function base10(str) {
return parseInt(str,2) //sxt
}
或
function MyParseInt(str, m){
if(str.slice(0,2) == "0x"){
str = str.slice(2)
m = 16
}
var sum=0;
for(var i=0;i<str.length;i++){
sum =sum*m+(str[i]-'0');
}
return sum
}
function base10(str) {
return MyParseInt(str,2)
}
或
function base10(str) {
var sum=0;
for(var i=0;i<str.length;i++){
sum =sum*2+(str[i]-'0');
}
return sum;
}
7-20
(1) 改变上下文:将函数 fn 的执行上下文改为 obj,返回 fn 执行后的值
function alterContext(fn, obj) {
return fn.call(obj) ;//sxt
}
(2) 判断是否包含数字:给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false
function containsNumber(str) {
var reg=/[0-9]/g;
return reg.test(str);
}
(3) 属性遍历:找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~)
1、返回数组,格式为 key: value
2、结果数组不要求顺序
function iterate(obj) {
var arrNew = [];
//使用for-in遍历对象属性
for(var key in obj){
//判断key是否为对象本身的属性
if(obj.hasOwnProperty(key)){
//将属性和值按格式存入数组
arrNew.push(key+": "+obj[key]);
}
}
return arrNew;
}
ps:
(1)解析url参数,并转换为对象
function getArg(str){ //key
var arr=str.split("?")[1].split("&");
var obj={};
var tmp={}
for(var i=0;i<arr.length;i++){
tmp=arr[i].split("=");
obj[tmp[0]]=tmp[1];
}
return obj;
}
var str="https://qq.com?pet=cat&age=2&lisk=fish";
console.log(getArg(str));
function serilizeUrl(url){ //同前一种方法
var result={};
url=url.split("?")[1];
var map=url.split("&");
for(var i= 0,len=map.length;i<len;i++){
result[map[i].split("=")[0]]=map[i].split("=")[1];
}
return result;
}
var str="https://qq.com?pet=cat&age=2&lisk=fish";
console.log(serilizeUrl(str));
(2)定时器、开始、暂停、重置
<div>
<button class="start">开始</button>
<button class="stop" >暂停</button>
<button class="reset">复位</button>
<!--<span class="txt"></span>-->
<span id="txt"></span>
<!--<input type="text" value="0" class="txt"/>-->
</div>
//var doc=document.getElementsByClassName("txt")[0];
var doc=document.getElementById("txt");
var btn=document.getElementsByTagName("button");
doc.innerText="";
var count=0;
var timer;
btn[0].onclick = function start(){ //开始
timer=setInterval(function(){
count++;
//doc.value=count;
doc.innerText=count;
},1000);
}
btn[1].onclick = function stop(){ //暂停
clearInterval(timer);
}
btn[2].onclick = function reset(){ //重置
clearInterval(timer);
doc.innerText=0;
}
7-21
(1) 给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false
function containsRepeatingLetter(str) {
var reg =/([A-Za-z])\1+/g ; //分组
var ret = reg.test(str)
return ret
}
(2) 给定字符串 str,检查其是否包含 连续3个数字
1、如果包含,返回最新出现的 3 个数字的字符串
2、如果不包含,返回 false
function captureThreeNumbers(str) {
var reg =/(\d){3}/g
var ret = str.match(reg)
if(ret == null ){
return false
}
return ret[0]
}
(3) 给定字符串 str,检查其是否符合如下格式
1、XXX-XXX-XXXX
2、其中 X 为 Number 类型
function matchesPattern(str) {
var reg =/^(\d){3}-(\d){3}-(\d){4}$/g //注意开始和结尾标记
var ret = reg.test(str)
return ret
}
未完待续。。。