文章中假如有毛病或许有更好的解法,请多多指出。
1.字符串去重
思绪:(1)应用对象key值唯一性
function unique(str){
var _obj=str.split('');
var length=str.length;
var result='';
var obj={};
for(var i=0;i<length;i++){
if(!obj[_obj[i]]){
obj[_obj[i]]='abc';
result+=_obj[i]
}
}
return result;
}
var str='oooooooooooopppppppppppppollllllllllsssssssss'
console.log(unique(str))
(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<length;i++){
if(!obj[arr[i]]){
obj[arr[i]]=1;
num++;
}else{
for( key in obj){
if(key==arr[i]){
obj[key]+=1;
}
}
}
}
for(key in obj){
if(obj[key]==1){
return key;
}
}
}
var str='wwccbbeeooppkkd'
console.log(firstUnique(str))
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<length;i++){
if(!obj[this[i]]){
obj[this[i]]='unique';
result.push(this[i])
}
}
return result;
}
var s=[1,1,1,1,1,2,2,4,4,4,5,5,5];
console.log(s.unique())
function distinct(ary){
var obj={};
for(var i=0;i<ary.length;i++){
var item=ary[i];
if(typeof obj[item]!=='undefined'){
ary[i]=ary[ary.length-1];
ary.length--;
i--;
continue;
}
obj[item]=item;
}
obj=null;
return ary;
}
var ary=[1,2,3,2,1,3]
console.log(distinct(ary))
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<length;i++){
array[i]=sum(origin[i])
}
array.sort(function(a,b){
return a-b;
})
return array[array.length-1]
}
function sum(item){
var isArray=item.constructor===Array;
var _sum=0;
if(isArray){
for(var i=0;i<item.length;i++){
_sum+=item[i].constructor===Array?sum(item[i]):item[i];
}
return _sum;
}else{
return item;
}
}
console.log(max(s))
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)