1.以下遞歸函數(shù)存在棧溢出的風險,請問如何優(yōu)化?
function factorial(n){
return n*factorial(n-1)
}
解答:
function factorial(n){
return n > 1 ? n * factorial(n-1) : 1;
}
2.請實現(xiàn)一個計算最大公約數(shù)的函數(shù):
function greatestCommonDivisor(a,b){
//在這里編寫代碼
}
greatestCommonDivisor(8, 12) //4
greatestCommonDivisor(8, 16) //8
greatestCommonDivisor(8, 17) //1
解答:
function greatestCommonDivisor(a,b){
var num=0;
while(b!=0){
num=a%b;
a=b;
b=num;
}
return a;
}
3.數(shù)組去重(如果數(shù)組中有NaN)
Array.prototype.uniq = function () {
var resArr = [];
var flag = true;
for(var i=0;i<this.length;i++){
if(resArr.indexOf(this[i]) == -1){
if(this[i] != this[i]){
//排除 NaN
if(flag){
resArr.push(this[i]);
flag = false;
}
}else{
resArr.push(this[i]);
}
}
}
return resArr;
}
4.用 JavaScript 實現(xiàn)斐波那契數(shù)列函數(shù),返回第n個斐波那契數(shù)市框。 f(1) = 1, f(2) = 1 等
function fibonacci(n) {
if(n ==1 || n == 2){
return 1
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
5.根據(jù)包名缘挽,在指定空間中創(chuàng)建對象
輸入描述:
namespace({a: {test: 1, b: 2}}, 'a.b.c.d')
輸出描述:
{a: {test: 1, b: {c: {d: {}}}}}
function namespace(oNamespace, sPackage) {
var properties = sPackage.split('.');
var parent = oNamespace;
for (var i = 0, lng = properties.length; i < lng; ++i) {
var property = properties[i];
if (Object.prototype.toString.call(parent[property])!== '[object Object]') {
parent[property] = {};
}
parent = parent[property];
}
return oNamespace;
}
6.封裝函數(shù) f,使 f 的 this 指向指定的對象
function bindThis(f, oTarget) {
return function(){
var parames = Array.prototype.slice.call(arguments);
return f.apply(oTarget,parames); //注意這里需要返回f的執(zhí)行結果
}
}
7.dom 節(jié)點查找
查找兩個節(jié)點的最近的一個共同父節(jié)點屡穗,可以包括節(jié)點自身
輸入描述:
oNode1 和 oNode2 在同一文檔中,且不會為相同的節(jié)點
function commonParentNode(oNode1, oNode2) {
if(oNode1.contains(oNode2)){
return oNode1;
}else if(oNode2.contains(oNode1)){
return oNode2;
}else{
return commonParentNode(oNode1.parentNode,oNode2);
}
}
8.關系型數(shù)組轉換成樹形結構對象
關系型數(shù)組:
var obj = [
{ id:3, parent:2 },
{ id:1, parent:null },
{ id:2, parent:1 },
]
期望結果:
o = {
obj: {
id: 1,
parent: null,
child: {
id: 2,
parent: 1,
child: {
id: ,3,
parent: 2
}
}
}
}
實現(xiàn)源碼:
function treeObj(obj) {
obj.map(item => {
if (item.parent !== null) {
obj.map(o => {
if (item.parent === o.id) {
if (!o.child) {
o.child = [];
}
o.child.push(item);
o.child = o.child;
}
});
}
});
return obj.filter(item => item.parent === null)[0]
}
或者:
function treeObj(obj) {
return obj.sort((a, b) => b.parent - a.parent)
.reduce((acc, cur) => (acc ? { ...cur, child: acc } : cur));
}
9.JS如何判斷一組數(shù)字是否連續(xù)
// 當出現(xiàn)連續(xù)數(shù)字的時候以‘-’輸出
[1, 2, 3, 4, 6, 8, 9, 10]
期望結果:
["1-4", 6, "8-10"]
實現(xiàn)代碼:
判斷是否連續(xù):
var arrange = function(arr){
var result = [],temp = [];
arr.sort(function(source, dest){
return source - dest;
}).concat(Infinity).reduce(function(source, dest){
temp.push(source);
if(dest-source > 1){
result.push(temp);
temp = [];
}
return dest;
});
return result;
};
格式化實現(xiàn):
var formatarr = function(arr) {
var newArr = []
var arr1 = arrange(arr)
for (var i in arr1) {
var str = '';
if (arr1[i].length > 1) {
str = arr1[i][0] + '-' + arr1[i][arr1[i].length - 1];
newArr.push(str)
} else {
newArr.push(arr1[i][0]);
}
}
return newArr;
}
10.創(chuàng)建子類Child,使用原型和構造函數(shù)的方式繼承父類People的方法咆瘟,并調用say函數(shù)說出姓名和年齡。
父類:
function People(name,age){
this.name=name;
this.age=age;
this.say=function(){
console.log("我的名字是:"+this.name+"我今年"+this.age+"歲诽里!");
};
}
原型繼承:
function Child(name, age){
this.name = name;
this.age = age;
}
Child.prototype = new People();
var child = new Child('Rainy', 20);
child.say()
構造函數(shù)繼承:
function Child(name, age){
People.call(this)
this.name = name;
this.age = age;
}
var child = new Child('Rainy', 20);
child.say()
組合繼承:
function Child(name, age){
People.call(this);
this.name = name;
this.age = age;
}
Child.prototype = People.prototype;
var child = new Child('Rainy', 20);
child.say()
組合繼承優(yōu)化:
function Child(name, age){
People.call(this);
this.name = name;
this.age = age;
}
Child.prototype = Object.create(People.prototype);
Child.prototype.constructor = Child;
var child = new Child('Rainy', 20);
child.say()