js 面试知识点

source: link.

js 数据类型

栈-基本数据类型:String、Number、Boolean 、Null、Undefined、Symbol、BigInt ;
堆-引用数据类型:Object Function;

undefined值派生自null,所以相等比较null==undefined为true;
null是空指针但未用,有个占位符,undefined连指针都没有,也没有占位符,所以绝对比较null===undefined为false

let _typeof = function (data) {
    let value = /\[object (\w+)\]/.exec(
        Object.prototype.toString.call(data)
    );
    return value ? value[1].toLowerCase() : '';
}
_typeof('123')      //"string"
_typeof(123)        //"number"
_typeof(123n)       //"bigint"
_typeof(null)       //"null"
_typeof(undefined)  //"undefined"
_typeof({})         //"object"
_typeof([])         //"array"
_typeof(/123/)      //"regexp"

获取当前年月日时分秒

function clock () {
  // 实例化当前时间
  let time = new Date();
  //年月日周
  let y = time.getFullYear(),
    m = time.getMonth() + 1,
    day = time.getDate(),
    week = toWeek(time.getDay());
  //小时,分钟,秒
  let h = time.getHours(),
    miu = time.getMinutes(),
    s = time.getSeconds(),
    ms = time.getMilliseconds();
  var resultTimne = `今天是 ${y}${m}${day}${week} ${h}${miu}${s}${ms}毫秒`;
  return resultTimne;
}
function toWeek (week) {
  let resuleWeek = '';
  switch (week) {
    case 0:
      resuleWeek = '日';
    case 1:
      resuleWeek = '一';
    case 2:
      resuleWeek = '二';
    case 3:
      resuleWeek = '三';
    case 4:
      resuleWeek = '四';
    case 5:
      resuleWeek = '五';
    case 6:
      resuleWeek = '六';
  }
  return '星期' + resuleWeek;
}
console.log(clock());
VM77:37 今天是 2020523日 星期六 124739400毫秒

换行

alert('朱朱朱\n安安安\n邦邦邦')

一排单选按钮,如何知道选择是第几个

var oInputs = document.getElementsByTagName('input');
for (let index = 0; index < oInputs.length; index++) {
  (function (index) {
    oInputs[index].onclick = function () {
      alert(index + 1)
    }
  })(index)
}

两相邻数的和等于下一项的值

function printFibonacci (n) {
  var arr = n > 0 ? [1] : [];
  if (n > 1) {
    for (let index = 1; index < n; index++) {
      arr.push(arr[index - 1] + (index >= 2 ? arr[index - 2] : 0))
    }
    return arr;
  }
}
console.log(printFibonacci(20));
[
    1,    1,    2,    3,    5,
    8,   13,   21,   34,   55,
   89,  144,  233,  377,  610,
  987, 1597, 2584, 4181, 6765
]

var a=(5).plus(3).minus(6)

不是数字类型有的方法,需要像数值的原型上写方法;
就是 Number.prototype;
Number.prototype.plus = function (n) {
  return this + n;
}
Number.prototype.minus = function (n) {
  return this - n;
}
var a = (5).plus(3).minus(6);
console.log(a);

输出document对象中所有成员的名称和类型

for(let key in document){
    document.write(key +'  :  '+ document[key]+'<br />');
}

Object.defineProperty(Object.prototype, 'myProperty', {
  configurable: true,
  enumerable: true,
  writable: true,
  value: 'This is my property'
})
let plainObj = {
  a: 1,
  b: 'string',
  c: true,
  fn: function (){
   return 1
  },
  arr: [1, { foo: function(){}}, 3, null],
  reg: /^#f{3}/
}
for ( let key in plainObj) {
  console.log(key) // a, b, c, fn, arr, reg, myProperty
}

for(let key of Object.keys(plainObj)){
  console.log(key) // a, b, c, fn, arr, reg
}

数组的遍历,可以用for-in、Array.prototype.forEach、还有for-of (可以与breakcontinuereturn配合使用)

用JS生成一个table

<div id='table11'></div>
<script>
  let row;
  let cell;
  for (let index = 0; index < 10; index++) {
    row = document.createElement('tr');
    document.getElementById('table11').appendChild(row);
    for (let j = 0; j < 5; j++) {
      cell = document.createElement('td');
      cell.innerText = '内容';
      row.appendChild(cell);
    }
  }
</script>

预加载一张图片

<img id ='imgObj' src='https://a.axihe.com/assets/img/anbang-weixin.jpg'/>
<script>
  var imgObj = document.getElementById('imgObj');
  function addImg (tempSrc) {
    var imgObj1 = new Image();
    imgObj1.src = tempSrc;
    imgObj1.onload = function () {
      imgObj.src = this.src;
      imgObj.height = 50;
      imgObj.width = 50;
    }
  }
  addImg('https://a.axihe.com/assets/img/bilibili.jpg');//这里是真正的显示文件
</script>

有一个4行td的table,将table里面的td顺序颠倒

将非数组集合转换为数组

appendChild为父元素添加子元素

table含有多个tBody,获取第一个tBody为tBodies[0].

通过call借用数组的slice方法

方法一:将元素集合迭代到数组中
let oTab = document.getElementById("tab1");
let oBody = oTab.tBodies[0];
let oTrs = oBody.rows;
let a = [];
for (let index = 0; index < oTrs.length; index++) {
  const element = array[index];
  a.push(element);
}
a.reverse();
for (let i = 0; i < a.length; i++) {
  const element = a[i];
  oBody.appendChild(element);
}
方法二:通过call借用数组的slice方法
let oTab = document.getElementById("tab1");
let oBody = oTab.tBodies[0];
let oTrs = oBody.rows;
let aRows = Array.prototype.slice.call(oRow, 0);
aRows.reverse();
for (let i = 0; i < aRows.length; i++) {
  const element = aRows[i];
  oBody.appendChild(element);
}

模拟一个HashTable类;包含add,remove,contains,length方法

定义类需要把函数名第一个字母大写(HashTable)。
this 关键字指向调用者。
为自定义类的原型添加方法。
push为数组追加项。
splice 是数组的方法,用来增、删、改数据。
function HashTale () {
  this.value = new Array();
}
HashTale.prototype.add = function (value) {
  this.value.push(value);
}
HashTale.prototype.remove = function (index) {
  this.value.splice(index, 1);
}
HashTale.prototype.contains = function (value) {
  let aValue = this.value;
  for (let index = 0; index < aValue.length; index++) {
    const element = aValue[index];
    if (value === element) {
      return true;
    }
  }
  return false;
}
HashTale.prototype.length = function (index) {
  return this.value.length;
}

函数绑定可以使用哪两个函数?函数绑定一般使用在什么情况下?这两个函数的区别是什么

李四 手机借我打个电话,我出话费
apply最多有2个参数,第一个参数是借用对象,第二个参数是数组类型。
call第一个参数为借用对象,后面的参数个数不限,都作为参数传递给被借用方法
function callFn () {
  let aArg = Array.prototype.slice.call(arguments, 0, 3);
  return aArg;
}
console.log(callFn('1', '2', '3', '4', '5', '6'))
输出结果:[ '1', '2', '3' ]
function applyFn () {
  let aArg = Array.prototype.slice.apply(arguments, [0, 3]);
  return aArg;
}
console.log(applyFn('1', '2', '3', '4', '5', '6'))
输出结果:[ '1', '2', '3' ]

func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
var  numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(Math, numbers),   //458
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215);   
//458

var n=(1,2,3,4,5),n的值是多少?
n的值是5,n中保存最后一次赋值。

如何判断数据类型

基本数据类型用typeof类获取
复杂数据类型object(是否是Array、Date类的实例)
借用toString方法;
var num=9;
console.log(typeof num);
var aNum=[1,3];
console.log(aNum instanceof Array);
let _typeof = function (data) {
    let value = /\[object (\w+)\]/.exec(
        Object.prototype.toString.call(data)
    );
    return value ? value[1].toLowerCase() : '';
}

var str=true+11+null+9+undefined+"zhuanbang"+false+null+9+[];
str的值是多少?为什么?
结果为 NaNzhuanbangfalsenull9,

因为undefined类型与任意数类型进行“+”运算结果都是NaN,NaN在与’zhuanbang’+false+null+9+[]运算,
由于’zhuanbang’是字符串类型,NaN是number类型,
NaN会隐式调用toString方法得到‘NaN,false是布尔类型当与字符串类型相加会隐式调用toString方法,得到’false,
9和空数组同样也是调用toString方法进行加运算。

function fn (max, min) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(fn(48, 30))

现在距离春节还有多少天,多少小时,多少分,多少秒;

function zero (val) {
  return Number(val) < 10 ? ('0' + val) : val
};
  
function fn () {
  var date1 = new Date();
  // var date2 = new Date(2022, 1, 1, 0, 0, 0);//传参的时候,传入的是(2022,1)而不是(2022,2...)
  var date2 = new Date("2022/02/01 0:0:0");//这样传入是没有问题的,不需要改
  var minutesVal = 60 * 1000;
  var dateValue = date2.getTime() - date1.getTime();
  var days = Math.floor(dateValue / (24 * 60 * minutesVal));
  var hoursValue = dateValue % (24 * 60 * minutesVal);
  var hours = Math.floor(hoursValue / (60 * minutesVal));
  var minutesValue = hoursValue % (60 * minutesVal);
  var minutes = Math.floor(minutesValue / minutesVal);
  var secondValue = minutesValue % (minutesVal);
  var second = Math.floor(secondValue / 1000);
  return {
    days: days,
    hours: zero(hours),
    minutes: zero(minutes),
    second: zero(second)
  }
}
var diffTime = fn();
var str = `相差 ${diffTime.days}${diffTime.hours}小时 ${diffTime.minutes}${diffTime.second}秒`;
console.log(str);
// document.write(str);
alert(Number("08"));输出的结果是什么?
输出结果为8。
八进制字面值的第一位必须是0,然后是八进制数字07,如果字面值中的数值超出了范围,那么前导的0将被忽略

找出name="A"的内容

<div name="A">1111</div>
<div name="B">2222</div>
<div name="A">3333</div>
var oDivs = document.getElementsByTagName('div');
var sValue = '';
for (let index = 0; index < oDivs.length; index++) {
  const item = oDivs[index];
  const attr = item.getAttribute('name');
  if (attr && (attr === 'A')) {
    sValue += (!sValue ? "" : ",") + item.innerText();
  }
}
console.log(sValue);

有问题?为什么?怎么解决?

<ul id="ul1"> 
    <li>node</li> 
    <li>node</li> 
    <li>node</li> 
    <li>node</li> 
    <li>node</li> 
</ul>
var eles=document.getElementById("ul1").getElementsByTagName("li");
var liLength=eles.length;
for(var i=0;i<liLength;i++){
  eles.item(i).parentNode.removeChild(eles.item(i))
}

参考答案
因为liLength的值是一直变化的,所以会有未删除项,

var oLis = document.getElementById('url1').childNodes;
while (oLis[0]) {
  oLis[0].parentNode.removeChild(oLis[0]);
}

闭包是一种机制

闭包的好处是避免变量冲突
缺点,就是如果闭包中有引用类型的数据被使用,那么整个闭包都无法释放,占用内存
闭包一般用在选项卡那类的异步操作,还有定时器的时候用;

创建闭包的常见方式是在一个函数内部创建另一个函数。通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。

外层函数不能访问内层,内层能访问外层
达到对变量的保护作用

function teachersInfo (propertyName) {
  return function (obj1, obj2) {
    return obj1[propertyName] + ' - ' + obj2[propertyName]
  }
}
//创建函数
var getTeachers = teachersInfo('name');
//调用函数
var resule = getTeachers({ name: "朱一" }, { name: "朱二" }, { name: "朱三" })
console.log(resule);//朱一 - 朱二
getTeachers = null;//释放这个句柄

闭包的特性
函数内再嵌套函数
内部函数可以引用外层的参数和变量
参数和变量不会被垃圾回收机制回收

function say667() {
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}
var sayAlert = say667();
sayAlert()//执行结果应该弹出的667  

0到59依次循环的计时器

var flag = 0;
function timer () {
  flag++;
  if (flag > 59) {
    flag = 0;
    return;
  }
  console.log(flag);
}
setInterval(timer, 1000);

add(2, 3, 4),add(2)(3)(4)和add(2, 3)(4)

下面的方法结果都是9;

console.log(add(2, 3, 4));
console.log(add(2)(3)(4));
console.log(add(2, 3)(4));

let _typeof = function (data) {
  let value = /\[object (\w+)\]/.exec(
    Object.prototype.toString.call(data)
  );
  return value ? value[1].toLowerCase() : '';
}
// 参数3个的时候,返回值
// 参数小于3的时候,返回函数,比如,1,2
function add (...arg) {
  // TODO转出数组
  let ary = [...arg];
  let sum = 0;
  // 相加
  ary.forEach(ele => {
    // 判断参数类型
    if (_typeof(ele) !== 'number') {
      throw Error(`不支持非数字类型;参数${ele} (${_typeof(ele)} 类型)`)
    }
    sum += ele;
  })
  // console.log(sum);
  // 返回
  if (ary.length >= 3) {
    return sum;
  }
  const _add = function () {
    if (arguments.length > 1) {
      throw Error(`暂时不支持链式调用多个参数`)
    }
    if (ary.length === 1) {
      return add(sum, ...arguments)
    }
    return add(sum, ...arguments, 0)
  }
  return _add;
}
console.log(add(2, 3, 4));
console.log(add(2)(3)(4));
console.log(add(2, 3)(4));

哪些操作会造成内存泄露

setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包
循环引用(在两个对象彼此引用且彼此保留时,就会产生一个循环)
DOM插入顺序
用任务管理器检查内存使用情况。在Chrome浏览器的新选项卡中打开应用并查看内存使用量是不是越来越多。

设立”严格模式”的目的

消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
默认支持的糟糕特性都会被禁用,比如不能用with
严格模式下的eval函数的行为和非严格模式的也不相同
也不能在意外的情况下给全局变量赋值;全局变量的显示声明;
函数必须声明在顶层,不允许在非函数代码块内声明函数,
限制函数中的arguments修改;arguments.callee也不允许使用;
提高编译器效率,增加运行速度;
为未来新版本的Javascript做好铺垫。

对 象的深度克隆代码实现

深拷贝代码
function clone(obj){
    if(typeof(obj) != 'object') return obj;
    var r = Array.prototype.splice === obj.splice ? []:{};
    for(var i in obj){
        if(obj.hasOwnProperty(i)){
            r[i] = clone(obj[i]);
        }
    }
    return r;
}
//数组、对象都可以for in,同时针对对象必须需要判断hasOwnProperty属性,以防克隆原型链上的属性
浅拷贝
Object.assign()

map 传了 3 个 (element, index, array)

let _typeof = function (data) {
  let value = /\[object (\w+)\]/.exec(
    Object.prototype.toString.call(data)
  );
  return value ? value[1].toLowerCase() : '';
}
var kvArray = ["1", "2", "3"];
var reformattedArray = kvArray.map(function (arg1, arg2, arg3) {
  console.log(`
  arg1:${arg1}, ${_typeof(arg1)}
  arg2:${arg2}, ${_typeof(arg2)}
  arg3:${arg3}, ${_typeof(arg3)}
  `)
  return parseInt(arg1, arg2, arg3)
});
console.log('---', reformattedArray)

document.querySelectorAll 方法

[].forEach.call($$("*"), function (a) {
  a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16)
})
Chrome浏览器的控制台中输入这段代码,你会发现不同HTML层都被使用不同的颜色添加了一个高亮的边框。是不是非常酷
$$("*") 函数是现代浏览器命令行的API的一部分,它等同于使用document.querySelectorAll 方法
document.querySelectorAll('*')来替代

查找页面所有类是edit的input,且type是text的元素,遍历他们并返回他们的value

var values = [];
$("input[type=text][.edit]").each(function (i, d) {
  values.push($(d).val());
});
<div id="anbang" class="class_1">anbang test</div>
<script>
    document.getElementById("anbang").className="class_2"
</script>

浏览器是否支持这些属性

首先看单个怎么来判断,可以下面这种的;
var element = document.createElement('div');
if ('text-overflow' in element.style) {
  element.style['text-overflow'] = 'ellipsis';
  return element.style['text-overflow'] === 'ellipsis';
} else {
  return false;
}
然后开始封装

var supports = (function () {
  var div = document.createElement('div'),
    vendors = 'Khtml Ms O Moz Webkit'.split(' '),
    len = vendors.length;
  return function (prop) {
    if (prop in div.style) return true;
    prop = prop.replace(/^[a-z]/, function (val) {
      return val.toUpperCase();
    });
    while (len--) {
      if (vendors[len] + prop in div.style) {
        // browser supports box-shadow. Do what you need.
        // Or use a bang (!) to test if the browser doesn't.
        return true;
      }
    }
    return false;
  };
})();
if (supports('textShadow')) {
  document.documentElement.className += ' textShadow';
}

input 元素在默认情况下显示“alipay WD Team”,而在光标移入后则显示空白?

placeholder 必须输入文字才会消失,所以不行,用 JS 实现

核心代码如下

onblur = this.value == '' ? this.defaultValue : this.value
onfocus = this.value == this.defaultValue ? '' : this.value

不通过第三个中间变量,交换2个变量的值

var a = 2;
var b = 5;
a = a + b;
b = a - b;
a = a - b;
console.log(a, b);//5 2
上面的加法换成乘法和除法也可以的;

var a = 2;
var b = 5;
a = b / a;
b = b / a;
a = b * a;
console.log(a, b);//5 2

字符串的常用方法

charAt 获取指定索引位置的字符
charCodeAt 获取指定索引位置的字符对应的ASCII码值
indeof/lasrIndexof 获取某个字符串在第一次(最后一次)出现位置的索引,没有的话返回-1,我们通常用这个来检测字符串中是否包含某一个字符;
toUpperCase/tolowerCase将字符串中的字母转大写|小写;
split按照指定的分隔符,讲一个字符串拆分成数组,和数组的join对应;
substr:substr(n,m)从索引n开始截取m个字符,把截取字符返回一个新的字符串;
substring:substring(n,m)从索引n开始截取到索引m处(不包含m),将找到的字符返回成一个新的字符串;
slice:slice(n,m)和substring的用法和意思一样,只是slice可以支持负数作为索引,出现负数索引的时候,用字符串的长度+负数索引,例如:ary.slice(-6,-2),其实是ary.slice(ary.length-6,ary.length-2)
上面三个方法,如果只写一个n,都是默认截取到字符串末尾的位置;
Replace:replace(“要替换的老字符”,“替换成的新字符”)字符串中字符替换的方法,可以应用正则来统一的进行替换,在正则中我们会详细的讲解replace的强大应用;
Match:把所有和正则匹配到的内容都进行捕获(不能捕获小分组中的内容)
trim: 去掉字符串中末尾位置的空白字符(不兼容)

parseQueryStr,它的用途是把URL参数解析为一个对象

var str = 'url=www.taobao.fm?name=zhu&age=26'
function parseQueryStr (str) {
  var obj = {};
  var aCourse = str.split("?")[1].split("&");
  for (let index = 0; index < aCourse.length; index++) {
    const currCou = aCourse[index].split("=");
    obj[currCou[0]] = currCou[1];
  }
  return obj
}
console.log(parseQueryStr(str)) //{name:zhu,age:26}

去除一个字符串开始和结尾的空格

String.prototype.trim = function () {
  var reg = /^\s+|\s+&/g;
  return this.replace(reg, '');
}
字符串中出现次数最多的字符;并统计此字符的个数
var str = “abcdefgaaaaaaddda”;
var obj = {};
var arr = [];
var letter;
for(var i = 0,len = str.length;i<len;i++){
   letter = str[i];
   if(!obj[letter]){
     obj[letter] = 1;
   }else{
     obj[letter]++;
   }
}
var max_key,max_num=0;
for(key in obj){
   if(max_num <obj[key]){
     max_num = obj[key];
     max_key = key;
   }
};    
document.write(“字母:”+max_key+” 次数:”+max_num);
实现千位分隔符方法
function commafy (num) {
  num = num + '';
  var reg = /(-?d+)(d{3})/;
  if (reg.test(num)) {
    num = num.replace(reg, '$1,$2');
  }
  return num;
}

字符串反转

var str="1234567890"
var resStr=str.split("").reverse().joim("");
console.log(revStr);

正则

o_div_style_position转成oDivStylePosotion

方法一:
var str = 'border-bottom-color';
var strRg = str.replace(/\-[a-z]/g, function (params) {
  return params.charAt(1).toUpperCase();
})
console.log(strRg);

方法二:
var str = 'border-bottom-color';
var aNew = [];
aNew = str.split('-');
for (let index = 0; index < aNew.length; index++) {
  if (index != 0) {
    aNew[index] = aNew[index].substr(0, 1).toUpperCase() + aNew[index].substr(1);
  }
}
str = aNew.join('');
console.log(str);

查找字符串中出现最多字符的个数sdjksfssscfssdd ->字符最多的是s,出现了7次

var str2 = 'sdjksfssscfssdd';
var obj = {};
var aNew = str2.split('');
for (let index = 0; index < aNew.length; index++) {
  const val = aNew[index];
  if (typeof obj[val] !== 'undefined') {
    obj[val]++;
  } else {
    obj[val] = 1;
  }
}
var maxObj = { key: null, count: null };
for (const key in obj) {
  var curr = obj[key];
  if (curr > maxObj.count) {
    maxObj.count = curr;
    maxObj.key = key;
  }
}
console.log(maxObj.key + ':' + maxObj.count);

用js实现千位分隔符? 123456789–>123,456,789

var str = '123456789';
var reg = /^([1-9]\d{0,2})((?:\d{3})+)$/;
var s = str.replace(reg, function () {
  return RegExp.$1 + ',' + RegExp.$2.match(/\d{3}/g);
})
console.log(s);//123,456,789

将第一个逗号前面的数字作为第一组,后面所有数字为第二组,
第二组是由多个三位的数字组合而成的,整体需要匹配捕获,但是每个三位数不需要匹配捕获所以加?:。
RegExp.$1获取第一个分组,RegExp.$2获取第二个分组。
match返回匹配到的数据,是数组类型。

var str = '123456789';
var reg = /^([1-9]\d{0,2})((?:\d{3})+)$/;
if (reg.test(str)) {
  var s = str.replace(reg, function () {
    return RegExp.$1 + ',' + RegExp.$2.match(/\d{3}/g);
  })
}
console.log(s);//123,456,789
------------------------------------
var count = 0;
var strNew = '';
var str1 = '60123761';
for (let i = str1.length; i >= 0; i--) {
  if (count % 3 === 0 && count != 0) {
    strNew += ',';
  }
  strNew += str1.substr(i, 1);
  count++;
}
strNew = strNew.split('').reverse().join('');
console.log(strNew);

一个正则表达式判断字符串是否是对称数

var str = 'Woow';
var reg = /^([a-z])([a-z])\2\1$/i;
if (reg.test(str)) {
  console.log('ok')
}

输入框中不能为空,如果有空格必须把空格去掉,必须是合法的手机号

<form action="" id="form1" method="get">
  电话号码:<input type="text" value="输入电话号码" id="mobi" name=""/>
  <input type="submit" name=""/>
</form>
var form1 = document.getElementById('form1');
form1.onsubmit = function () {
  var mobi = document.getElementById('mobi');
  var reg = /^1\d{10}$/;
  if (reg.test(mobi.value.replace(/ /g, ''))) {
    console.log('ok');
  } else {
    console.log('error');
    return false;
  }
}

分解超链接

var str = '<a href="https://www.axihe.com/">阿西河</a>
<a href="https://www.axihe.com/?name=anbang&age=30&tit=web">阿西河</a>';
var reg = /<a href=([\"\'])([^'"]+)\1>([^'"]+)<\/a>/g;
var a = [];
while (true) {
  reg.test(str);
  if (reg.lastIndex === 0) {
    break;
  }
  a.push({ name: RegExp.$3, url: RegExp.$2 });
}
for (const n in a) {
  for (const attr in a[n]) {
    console.log(a[n][attr]);
  }
}
// 阿西河
// https://www.axihe.com/
// 阿西河
// https://www.axihe.com/?name=anbang&age=30&tit=web

匹配由数字和大写字母组成的字符串

function checkPassWord (nubmer) {
  var re = /^[0-9a-zA-Z]*$/;  //判断字符串是否为数字和字母组合
  if (!re.test(nubmer)) {
    return false;
  } else {
    return true;
  }
}

Js 创建对象的几种方式

1、对象字面量的方式
person={
  firstname:"zhu",
  lastname:"anbang",
  age:25,
  eyecolor:"black"};

2、用function来模拟无参的构造函数
function Person(){}
    var person=new Person();//定义一个function. 如果使用new"实例化",该function可以看作是一个Class
    person.name="zhu";
    person.age="25";
    person.work=function(){
      alert(person.name+" hello...");
}
person.work();

3、用function来模拟参构造函数来实现(用this关键字定义构造的上下文属性)
function Pet(name,age,hobby){
    this.name=name;//this作用域:当前对象
    this.age=age;
    this.hobby=hobby;
    this.eat=function(){
      alert("我叫"+this.name+",我喜欢"+this.hobby+",是个程序员");
    }
}
var maidou =new Pet("麦兜",25,"coding");//实例化、创建对象
maidou.eat();//调用eat方法

4、用工厂方式来创建(内置对象)
var wcDog =new Object();
wcDog.name="旺财";
wcDog.age=3;
wcDog.work=function(){
  alert("我是"+wcDog.name+",汪汪汪......");
}
wcDog.work();

5、用原型方式来创建
function Dog(){}
Dog.prototype.name="旺财";
Dog.prototype.eat=function(){
alert(this.name+"是个吃货");
}
var wangcai =new Dog();
wangcai.eat();

6、用混合方式来创建
function Car(name,price){
  this.name=name;
  this.price=price; 
}
Car.prototype.sell=function(){
  alert("我是"+this.name+". 我现在卖"+this.price+"万元");
}
var camry =new Car("凯美瑞",27);
camry.sell();

单利模式

function Construct () {
  //确保只有单例
  if (Construct.unique !== undefined) {
    return Construct.unique;
  }
  //其他代码
  this.name = 'anhang';
  this.age = '25';
  Construct.unique = this;
}
var t1 = new Construct();
var t2 = new Construct();
-----------------------------------
var single = (function () {
  var unique;
  function Construct () {
    //确保只有单例
    if (Construct.unique !== undefined) {
      return Construct.unique;
    }
    //其他代码
    this.name = 'anhang';
    this.age = '25';
    Construct.unique = this;
  }
  unique = new Construct();
  return unique;
})()

继承的实现方法有哪些

function Parent (firstname) {
  this.fname = firstname;
  this.age = 30;
  this.sayAge = function () {
    console.log(this.age)
  }
}
function Child (firstname) {
  this.saySomeThing = function () {
    console.log(this.fname)
    this.sayAge();
  }
  this.getName = function () {
    return firstname;
  }
}
var child = new Child('anbang')
Parent.call(child, child.getName())
child.saySomeThing();

-----------------
function Parent (firstname) {
  this.fname = firstname;
  this.age = 30;
  this.sayAge = function () {
    console.log(this.age)
  }
}
function Child (firstname) {
  this.saySomeThing = function () {
    console.log(this.fname)
    this.sayAge();
  }
  this.getName = function () {
    return firstname;
  }
}
var child = new Child('anbang')
Parent.apply(child, [child.getName()])
child.saySomeThing();
-----------------
function Parent () {
  this.sayAge = function () {
    console.log(this.age)
  }
}
function Child (firstname) {
  this.fname = firstname;
  this.age = 30;
  this.saySomeThing = function () {
    console.log(this.fname)
    this.sayAge();
  }
}
Child.prototype = new Parent();
var child = new Child('anbang')
child.saySomeThing();
---------------------
function Parent () {
  this.sayAge = function () {
    console.log(this.age)
  }
}
Parent.prototype.sayParent = function () {
  console.log("sayParent")
}
function Child (firstname) {
  Parent.call(this);
  this.fname = firstname;
  this.age = 30;
  this.saySomeThing = function () {
    console.log(this.fname)
    this.sayAge();
  }
}
Child.prototype = new Parent();
var child = new Child('anbang')
child.saySomeThing();
child.sayParent();

模块化开发怎么做

var module1 = (function () {
  var _count = 0;
  var m1 = function () {
    //...
  };
  var m2 = function () {
    //..
  };
  return {
    m1: m1,
    m2: m2
  };
})();

求数组中的最大值

var a = [3, 4, 6, 2, 9, 11, 4];
var maxNum = Math.max.apply(null, a);
console.log(maxNum);//11

ary.sort(function(a,b){return a-b})
console.log(ary[0]);
console.log(ary[ary.length-1]);

数组去重

Array.prototype.distinct = function () {
  var a = this;
  for (let index = 0; index < a.length - 1; index++) {
    for (let i = index + 1; i < a.length;) {
      if (a[index] == a[i]) {
        a.slice(i, 1);
      } else {
        i++
      }
    }
  }
  return a;
}
----------------------------------------------------------------var arr = [3, 2, 3, 1, 4, true, false, "3", "22", "2", 2]
function norepeat (arr) {
  var resArr = [];
  var obj = {};
  for (var i = 0, len = arr.length; i < len; i++) {
    if (!(obj[arr[i] + typeof arr[i]])) {
      resArr.push(arr[i]);
      obj[arr[i] + typeof arr[i]] = 1;
    }
  }
  return resArr;
}
var res = norepeat(arr);
console.log(res);
-------------------------
function noRepeat (arr) {
  var obj = {}
  for (var i = 0, len = arr.length; i < len; i++) {
    var cur = arr[i];
    if (obj[cur] == cur) {
      arr.splice(i, 1);
      i--;
      continue;
    }
    obj[cur] = cur;
  }
  return = null;
}

计算出班级的平均分(保留整数)

funtion average(){
  var a = arguments;
  [].sort.call(a, function (a, b) {
    return a - b
  });
  [].pop.call(a);
  [].shift.call(a);
  var count = null;
  var count = eval([].join.call(a, "+"));
  return count / a.length;
}
var sore = average(45, 56, 23, 18, 90, 100)

数组的方法和属性

var a=new Array;
a.concat(arr1,,arryN);  //将arr1…arryN数组与a合并成一个新数组返回,原数组不变。
a.join(,);  //将数组a中各项以逗号(,)拼接成一个字符串返回
a.push(value) //将value追加到a最后一项,a.length自动加1
a.pop();  //删除a数组最后一项,a.length自动减1
a.unshift(val); //在a第0项插入val值,原数据项向后移位,a.length自动加1
a.shift();  //删除a第0项,a.length自动减1
a.reverse() //将a中数据反转
a.slice(indexA,indexB); //复制索引从indexA到indexB-1为一个新数组,原数组不变,不包括indexB项,通常这种传入2个索引的方法,第二个参数都不参与运算,indexB-1参与运算。
a.sort()  //对a进行排序,但排序是按照ASCII表排序,会将13排在2前面。如果想按照正常排序,如下:
var a = [5, 67, 1, 2, 4];
a.sort(function (x, y) {
return x - y;
})
console.log(a);
splice(index,count,ele1,,ele2);  //index是起始索引,count表示从index开始要删除的个数,后面的参数表示从index开始插入的值,例如:

var a = [5, 67, 1, 2, 4];
a.splice(1, 2, 88, 99);
console.log(a);

改变原数组的方法:pop()、push()、reverse()、shift()、sort()、splice()、unshift()
不改变原数组的方法:concat()、join()、slice()、toString()

数组里面的数组替换成中文;

var a = ['壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖', '拾', '佰', '仟', '万', '亿'];
var arr = ['壹', '贰', 3, 4, '伍'];
var ss = arr.toString().replace(/\d/g, function (n) {
  return a[n];
})
console.log(ss);
同类题:将112299转换成中文:

var a = ['壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖', '拾', '佰', '仟', '万', '亿'];
var n = 112299;
var str = n.toString().replace(/\d/g, function (n) {
  return a[n];
})
console.log(str);
注意:

1) /\d/ 正则中表示匹配数字。
2) replace 其实传给参数 function 三个参数,第一个是匹配到的值,第二个是所在索引,第三个是被索引的整个字符串。

删除数组中的第m项到第n项,用什么方法

var a = [1, 2, 5, 6, 7, 8, 9];
console.log(dele(a, 1, 3));
function dele (a, m, n) {
  a.splice(m, n - m + 1);
  return a;
}

数字数据为function数组

var arr = [3, 5, 12, 55, 12, 321, 41, 0, 999];
Array.prototype.toFunction = function () {
  for (let index = 0; index < this.length; index++) {
    this[index] = (function (a) {
      return function () {
        return a;
      }
    })(this[index])
  }
  return this;
}
arr.toFunction();
console.log((arr[5])()) // 321

给Object数组进行排序(排序条件是每个元素对象的属性个数)

var obj1 = { att1: 0, attr2: 0, att3: 0, att4: 0 };
var obj1 = { att1: 0, attr2: 0, att3: 0, att4: 0, att5: 0 };
var obj1 = { att1: 0, attr2: 0, att3: 0, att4: 0, att5: 0, att6: 0 };
var aObjs = [obj1, obj2, obj3];
aObjs.sort(function () {
  for (let index = 0; index < 2; index++) {
    arguments[i].length = 0;
    for (const key in arguments[i]) {
      if (arguments[i].hasOwnProperty(key)) {
        arguments[i].length++;
      }
    }
  }
  return arguments[0].length - arguments[1].length;
})
console.log(aObjs);

js对象的深度克隆

function clone (Obj) {
  var buf;
  if (Obj instanceof Array) {
    buf = [];  //创建一个空的数组 
    var i = Obj.length;
    while (i--) {
      buf[i] = clone(Obj[i]);
    }
    return buf;
  } else if (Obj instanceof Object) {
    buf = {};  //创建一个空对象 
    for (var k in Obj) {  //为这个对象添加新的属性 
      buf[k] = clone(Obj[k]);
    }
    return buf;
  } else {
    return Obj;
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值