文章中如果有错误或者有更好的解法,请多多指出。
1.字符串去重
思路:(1)利用对象key值唯一性
function unique(str){
var _obj=str.split('');
var length=str.length;
var result='';
var obj={};
for(var i=0;i
(2)方法2 利用Set (谢谢道友们的分享)
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
const unique = str => [...new Set(str.split(""))].join("");
var str='oooooooooooopppppppppppppollllllllllsssssssss'
console.log(unique(str)) // opls
2.查找出在字符串中只出现一次的第一个字符
举例-str='pppwrtto' ===> 输出 w
思路:
1.str去重 [p,w,r,t,o] 同时将字符出现的次数记录下来,组成如下结构
{p:3,w:1,r:1,t:2,o:1}
2.判断当第一次obj[key]==1的时候就返回key值
function firstUnique(str){
var arr=str.split('');
var length=arr.length;
var obj={};
var num=0;
for(var i=0;i
3.封装typeof(重点区分 引用值---1.数组,2.对象,3.包装类)
思路:1.区分原始值 引用值 2.原始值 引用值
function type(target){
//原始值 引用值
//区分引用值
var template={
"[object Array]":'array',
"[object Object]":'object',
"[object Number]":'number-object',
"[object Boolean]":'boolean-object',
"[object String]":'string-object'
}
if(target===null){
return 'null';
}else if(typeof(target)=='object'){
// 数组
// 对象
// 包装类 Object.prototype.toString
var str=Object.prototype.toString.call(target);
return template[str];
}else{
return typeof(target)
}
}
console.log(type('abc'))
console.log(type(function(){}))
console.log(type([]))
console.log(type({}))
console.log(type(new Number()))
console.log(type(new Object()))
console.log(type(new String()))
console.log(type(new Boolean()))
console.log(type(new Array()))
4.数组去重--在原型链上进行
var arr=[1,1,2,2,'a','a']
arr.unique-->[1,2,a]
思路:通过对象 hash方式
Array.prototype.unique=function(){
var obj={};
var result=[];
var length=this.length;
for(var i=0;i
function distinct(ary){
var obj={};
for(var i=0;i
5.Js实现方法连续调用
var demo={
smoke:function(){
console.log("吸烟")
return this;
},
eat:function(){
console.log('吃饭')
return this;
},
perm:function() {
console.log('烫头')
return this;
}
}
demo.smoke().eat().perm()
6.低耦合写出阶乘函数
--消除紧密耦合的现象,可以像下面这样使用 arguments.callee(严格模式下callee失效)
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1)
}
}
console.log(factorial(3))
7.&&与||运算符
var a=1&&2; //&& 如果第一个表达式为真,将返回第二个表达式值返回
console.log(a);
var b=1&&2+2;
console.log(b);
var c=0&&2; //&& 如果第一个表达式为假,将返回第一个表达式值返回
console.log(c)
var d=1||2;//|| 第一个表达式为真,则直接返回
console.log(d)
var e=0||2;//|| 第一个表达式为假,则返回第二个值
console.log(e)
2>1&&document.write('hello');
var data;
data&&console.log('ni hao')
8.浅拷贝
我们知道引用类型的赋值其实是改变了变量的指向,那么如果在需要拷贝的对象中存在某个属性的值是引用类型,如数组或子对象,那么浅拷贝后的原对象的属性获得的也只是这个指向。所以如果改变被拷贝对象的属性值,那么原对象的相应属性也会跟着改变
function extendCopy(p) {
var c = {};
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
return c;
}
9.深拷贝
递归
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
}
var chinese={
nation:'中国',
minzu:{name1:'汉族',name2:'苗族'}
}
var Doctor = deepCopy(Chinese);
数组&对象深拷贝
function deepCopy(origin) {
if (typeof origin != 'object') {
return origin;
}
var result;
if(Object.prototype.toString.call(origin)=== '[object Array]'){
result=[];
for(var i in origin){
result[i]= typeof origin[i]==='object'?deepCopy(origin[i]):origin[i];
}
}else{
result={};
for (var key in origin) {
if(origin.hasOwnProperty(key)){
result[key]= typeof origin[key]==='object'?deepCopy(origin[key]):origin[key];
}
}
}
return result;
}
var obj1={
name:'小黄',
sister:{name:'花花',age:20},
grade:[10,20,30,[89,60]]
};
var obj2=deepCopy(obj1)
10.函数预编译 GO与AO
最终
GO{
a:100,
demo:function(){},
f:123
}
AO{
e:2,
b:undefined,
a:10
}
a=100;
function demo(e){
function e(){}
arguments[0]=2;
console.log(e); //2
if(a){
var b=123;
}
a=10;
var a;
console.log(b);//undefined
f=123;
console.log(a);//10
}
var a;
demo(1);
console.log(a); //100
console.log(f); //123
11.将 var obj={value0:'1',remark0:'备注1',value1:'2',remark1:'备注2'}; 转换为[{value0:'1',remark0:'备注1'},{value1:'2',remark1:'备注2'}]
var obj={value0:'1',remark0:'备注1',value1:'2',remark1:'备注2'};
var count=0;
var result=[];
var storage={};
for(var key in obj){
count++;
storage[key]=obj[key]
if(count%2==0){
result[count/2-1]=storage;
storage={};
}
}
console.log(result);
12.输入一个整形数组,数组中有正数也有负数,数组中连续的一个或多个数组组成一个子数组,每个子数组都有一个和,求所有子数组和的最大值。
var s=[20,[1,2,10],[-2,30,[-1,-1,-8]]];
function max(origin){
var length=origin.length;
var array=[]
for(var i=0;i
13、call原理以及面试题
原理:
Function.prototype.call=function call(context){
//native code
//把指定函数中的this指向context =>也就是fn this改变 -------[把this(call中的this)中的this指向context]
//把指定函数执行 fn执行---- [this执行] this()
}
//以下都是让call方法执行
//fn.call(opp) //call方法中的this 是fn
//fn.__proto__.call(); //call方法中的this是fn.__proto__
//Function.prototype.call(); //call this=>Function.prototype
题目:
function fn1(){
console.log(1);
}
function fn2(){
console.log(2)
}
fn1.call(fn2);
//fn1.call :fn1这个Function的实例通过__proto__找到Function.prototype上的call方法,然后让call方法执行(传递fn2这个实参)
//执行call的时候,call中的this:fn1,所此处是把fn1执行,让fn1中的this执行fn2
fn1.call.call.call(fn2);
//f1.call.call.call 依然是找到原型上的call方法并且让call执行。
// call3中的this:fn1.call.call[原型上的call]
// call3中的Context:fn2
// 1. 让【原型中的call(fn1.call.call)】中的this指向fn2
// 2. 让[原型上的call(fn1.call.call)]执行
// -1、第二次执行原型上的call,只不过此时的call已经变为了fn2
// -2、让指定函数fn2中的this指向undefined
// -3、让fn2执行
Function.prototype.call(fn2);
// 找到原型上的call方法,让call执行
// call执行:
// this:Function.prototype
// context:fn2
//
// 把Functon.prototype中的this关键字变为fn2
// 让Function.prototype执行
// ==>无输出(匿名空函数执行无输出)
Function.prototype.call.call.call(fn2);
// 等价于 fn1.call.call.call(fn2)
14、阿里面试题目
function Foo(){
getName=function(){
console.log(1)
};
return this;
}
Foo.getName=function(){
console.log(2);
}
Foo.prototype.getName=function(){
console.log(3)
}
var getName=function(){
console.log(4)
}
function getName(){
console.log(5)
}
Foo.getName() //把Foo作为对象,找其私有属性
getName();// 执行全局下的getName
Foo().getName(); //先将Foo作为普通函数执行,然后在调取getName
getName();
new Foo.getName()//先获取Foo.getName的值(假设B),然后在new B()相当于创建B的实例
new Foo().getName() //先new Foo() 获取实例(new Foo()相当于将Foo函数有重新执行了一遍,此时getName->1),把得到的实例再调取getName
new new Foo().getName();//=>var f=new Foo() new f.getName() =>[new (f.getName)]()
15、数组去重《链式写法》
Array.prototype.myDistinct=function myDistinct(){
var obj={};
for (var i = 0; i < this.length; i++) {
var item=this[i];
if(typeof obj[item]!=='undefined'){
this[i]=this[this.length-1];
this.length-1;
i--;
continue;
}
obj[item]=item;
}
obj=null;
return this;
}
var ary=[1,2,3,4,1,2,44,3]
ary.myDistinct();
ayy.myDistinct.sort();
16.闭包、作用域、变量提升
var num=1,
obj={
num:2,
fn:(function(num){
this.num*=2;
num+=2;
return function(){
this.num*=3;
num++;
console.log(num)
}
})(num)
}
var fn=obj.fn;
fn();
obj.fn();
console.log(num,obj.num)