前端javascript知识(三)
- 函数记忆,判断是不是质数.
方法一:
function isPrime1(n){
if(n<=3){return true}
else{
for(var i=2;i<Math.sqrt(n);i++){
if(n%i==0){return false;}
}
return true;
}
};
方法二:hash
var isPrime2=(function(){//hash
var hash={};
return function(n){
if(n<=3){return true}
else if(hash[n]!==undefined){
return hash[n];
}else{
for(var i=2;i<Math.sqrt(n);i++){
if(n%i==0){return hash[n]=false}
}
return hash[n]=true;
}
}
})(); - 数组去重
方法一:
var arr1=[1,2,3,2,1,2];
function repeat1(arr){
for(var i=0,arr2=[];i<arr.length;i++){
if(arr2.indexOf(arr[i])==-1){
arr2.push(arr[i]);
}
}//(遍历结束)
return arr2;
}
方法二:hash
function repeat2(arr){
//遍历arr中每个元素,同时声明hash
for(var i=0,hash={};i<arr.length;i++){
//hash中是否包含当前元素值的建
//如果不包含,就hash添加一个新元素,以当前元素值为key,value默认为1
if(hash[arr[i]]===undefined){
hash[arr[i]]=1;
}
}//(遍历结束)
//将hash转为索引:
var i=0;
var arr2=[];
for(arr2[i++] in hash);
return arr2;
}
方法三:
function repeat3(arr){
return arr.sort()
.join(",,")
.replace(
/(^|,,)([^,]+)(,,\2)*/g,
"$1$2")
.split(",,");
}
console.log(repeat3(arr1)); - 插入排序
var arr=[2,4,1,5,3];
function insertSort(arr){
//遍历arr中每个元素(i从1开始)
for(var i=1;i<arr.length;i++){
//将当前元素临时保存在变量t中
var t=arr[i];
var p=i-1;//声明变量p=i-1
//循环:(arr[p]>t&&p>=0){
while(arr[p]>t&&p>=0){
//将p位置的值,赋值给p+1位置
arr[p+1]=arr[p];
p--;//p--
}//(循环结束)
arr[p+1]=t;//将t放在p+1的位置上
}//(循环结束)
}
insertSort(arr);
console.log(String(arr)); - 快速排序:
function quickSort(arr){
//如果arr的length<=1
if(arr.length<=1){
return arr;//就直接返回arr
}
//计算参照位p
var p=Math.floor(arr.length/2);
var left=[];
var right=[];
//删除p位置的元素
var center=arr.splice(p,1)[0];
//遍历arr中每个元素
for(var i=0;i<arr.length;i++){
if(arr[i]>=center){
right.push(arr[i]);
}else{
left.push(arr[i]);
}
}
return quickSort(left) .concat(center,quickSort(right))
}
var sortedArr=quickSort(arr);
console.log(String(sortedArr)); - 正则表达式
(1) "ryan5 is6 not7 a8 good9 man10"
var n=5;
var str="ryan is not a good man";
str=str.replace(/\b[a-z]+\b/g,function(kw){ return kw+n++;});
console.log(str); - 统计字符串中每种字符出现的次数,出现次数最多的是? 出现?次
var str="helloworld";
方法一:用hash
for(var i=0,hash={};i<str.length;i++){
if(hash[str[i]]){
hash[str[i]]++
}else{
hash[str[i]]=1;
}
}
console.dir(hash);
方法二:用正则
var arr=str.split("")
.sort()
.join("")
.match(/([a-z])\1*/g)
.sort(function(a,b){
return b.length-a.length; })
console.log("出现最多的是: "+arr[0][0]
+"共"+arr[0].length+"次");
var hash={};
arr.forEach(function(val){
hash[val[0]]=val.length;
});
console.dir(hash); - 数组降维
var arr=[
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
];
//method 1:
for(var r=0,arr1=[];r<arr.length;r++){
for(var c=0;c<arr[r].length;c++){
arr1.push(arr[r][c]);
}
}
console.dir(arr1);
//method 2:
for(var r=0,arr2=[];r<arr.length;r++){
arr2=arr2.concat(arr[r]);
}
console.dir(arr2);
//method 3:
var arr2=[].concat.apply([],arr);
console.dir(arr2); - Function赋值
var f=function(){var a=b=1;}
f();
console.log(b);//1
console.log(a);//报错
var f=function(){var a=b=1;}
setTimeout(f,0);
console.log(b);//报错
f();
var a,b=0, fn=function(){var a=b=2;}
fn();
console.log(a);//undefined
console.log(b);//2 - 函数currying(柯里华)
var getN;
function add(n){
getN=function(){console.log(n);}
return function(m){
n+=m;
arguments.callee.toString=function(){
return n;
}
return arguments.callee;
}
}
add(1)(2)(3); getN();//6
add(1)(2)(3)(4); getN();//10
alert(add(1)(2)(3));//6
alert(add(1)(2)(3)(4));//10 - 递归
var emp={
work:function(){//3,2,1
var sum=0;//+3+2+1 +2+1 +1
for(vari=0; i<arguments.length&&arguments[0]>0;
i++){
sum+=arguments[i]
+arguments.callee(
--arguments[i]
);
}
return sum;
}
}
console.log(emp.work(3,2,1));//10 - 闭包
(1)function fun(n,o){//外层函数
console.log(o);
return {
fun:function(m){//内层函数 n
return fun(m,n);
}
}
}
var a=fun(0);a.fun(1); a.fun(2); a.fun(3);
//undefined 0 0 0
var a=fun(0).fun(1).fun(2).fun(3);
//undefined 0 1 2
var a=fun(0).fun(1); a.fun(2); a.fun(3);
//undefined 0 1 1
(2)var a=0,b=0;
function A(a){
A=function(b){alert(a+b++)};
alert(a);
}
A(1);//1
A(12);//13 - OOP
(1)
window.a=300;
function fn1(){
this.a=100;
this.b=200;
return function(){
alert(this.a)
}.call(arguments[0])
}
function fn2(){ this.a=new fn1(); }
var a=new fn1().b;//300
var v=new fn1(fn2());//[object Object]
(2)
var number=2;//4 8
var obj={
number:4,//8
fn1:(function(){
//var number;
this.number*=2;
number*=2; //声明提前 undefined
var number=3;
return function(){
this.number*=2;
number*=3;
alert(number);
}
})()
}
var fn1=obj.fn1;
alert(number); fn1(); obj.fn1();
//4 9 27
alert(window.number);//8
alert(obj.number);//8
(3)
function Foo(){
getName=function(){alert(1);};
return this;
}
Foo.getName=function(){alert(2);};
Foo.prototype.getName=function(){
alert(3);
};
var getName=function(){alert(4);};
function getName(){ alert(5); };
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3
(4)
var a=1;
var b={
a:2,
b:function(){
console.log(this.a);//1
}(),
f:this.f=function(){
console.log(this.a);
}
};
function f(){ console.log(3); }
f();//1
b.f();//2
(b.f)();//2
(0,b.f)();//1
(5)
var foo=function(){
console.log(this.a);
}
var obj={a:2,foo:foo};
var a=10;
var bar=obj.foo;
var bar2=foo.bind(obj);
bar();//10
bar2();//2
foo();//10
obj.foo();//2
setTimeout(bar,0);//10
(6)
function MyObj(){
this.p.pid++;
}
MyObj.prototype.p={"pid":0}//2
MyObj.prototype.getNum=function(num){
return this.p.pid+num;
}
var _obj1=new MyObj(); //创建新对象,继承原型pid+1
var _obj2=new MyObj(); //创建新对象,继承原型pid+2
console.log(
_obj1.getNum(1)+_obj2.getNum(2)
);//7 2+1 + 2+2 - 判断一个对象是不是数组类型,有五种方法:
(1) typeof 无法判断 只能判断原始类型的值和函数
(2)isPrototypeOf 判断父及对象 可检查整个原型链 //可能继承自数组
console.log(Array.prototype.isPrototypeOf([])?"是数组":"不是数组");
console.log(Array.prototype.isPrototypeOf({})?"是数组":"不是数组");
console.log(Array.prototype.isPrototypeOf(function(){})?"是数组":"不是数组");
(3)constructor 检查指定对象的构造函数 可检查整个原型链 //可能继承自数组
var father={};
var son={};
father.__proto__=Array.prototype;
son.__proto__=father;
console.log(son.contructor==Array?"是数组":"不是数组")
console.log({}.contructor==Array?"是数组":"不是数组");
console.log(function(){}.contructor==Array?"是数组":"不是数组");
(4)instanceof 检查一个对象是否是制定构造函数的实例 可检查整个原型链 //可能继承自数组
var father={};
var son={};
father.__proto__=Array.prototype;
son.__proto__=father;
console.log(son instanceof Array?"是数组":"不是数组");
console.log({} instanceof Array?"是数组":"不是数组");
console.log(function(){} instanceof Array?"是数组":"不是数组");
(5)强行用要检查的对象,调用原始的toString方法 不检查整个原型链
//[object class]: class-Array Date Object
//只能检查最初就是数组创建的对象。
console.log(Object.prototype.toString.call([])=="[object Array]"?"是数组":"不是数组");
console.log(Object.prototype.toString.call({}));
console.log(Object.prototype.toString.call(function(){}));
console.log(Object.prototype.toString.call(/\d/));
var father={};
var son={};
father.__proto__=Array.prototype;
son.__proto__=father;
console.log(Object.prototype.toString.call(son)=="[object Array]"?"是数组":"不是数组");//不是
//结论: 对象一旦创建,class属性就无法修改
//修改继承关系,也无法修改class属性
(6) Array.isArray(obj) 不检查整个原型链
console.log(Array.isArray([]));
console.log(Array.isArray({}));
//如果浏览器不支持isArray
if(Array.prototype.isArray===undefined){//if(!Array.isArray)
//给?添加isArray方法
Array.prototype.isArray=function(arg){
//强行调用原始toString方法,和"[object Array]"比较
return Object.prototype.toString.call(arg)
=="[object Array]"?"是数组":"不是数组";
}
} - 自定义Object.create()——手写
Object.create=function(father,props){
console.log("我的create");
/*使用setPrototypeOf方法
var o=Object();//1. 创建空对象
Object.setPrototypeOf(o,father);//2. 继承father
*/
/*不使用setPrototypeOf方法
function Constructor(){}
Constructor.prototype=father;
var o=new Constructor();
*/
Object.defineProperties(o,props);//3. 定义新属性
return o;
} - 深克隆原理
Object.clone=function(obj){//深克隆
if(typeof(obj)=="object"){//如果obj是对象
var o=//有必要区分数组和普通对象
Object.prototype.toString.call(obj)=="[object Array]"?[]:{};
for(var key in obj){//遍历obj的自有属性
//如果key是obj的自有属性
if(obj.hasOwnProperty(key)){
o[key]=arguments.callee(obj[key]);//arguments.callee调的是当前的Object.clone函数
}
}
return o;
}else{//如果obj是原始类型的值,就直接返回副本
return obj;
}
} - 如果浏览器不支持every属性,every的实现原理
if(Array.prototype.every===undefined){
Array.prototype.every=function(fun){
//遍历当前数组中每个元素
for(var i=0;i<this.length;i++){
if(this[i]!==undefined){
//调用fun,依次传入当前元素值,位置i,当前数组作为参数 ,将返回值,保存在变量r中
var r=fun(this[i],i,this);
if(r==false){//如果r为false
return false;//返回false
}
}
}//(遍历结束)
return true;//返回true
}
} - 如果浏览器不支持some属性,some的实现原理
if(Array.prototype.some===undefined){
Array.prototype.some=function(fun){
for(var i=0;i<this.length;i++){
if(this[i]!==unefined){
var r=fun(this[i],i,this);
if(r==true){ return true; }
}
}
return false;
}
} - 浏览器不支持map属性,map的实现原理
if(Array.prototype.map===undefined){
Array.prototype.map=function(fun){
//创建空数组: newArr
var newArr=[];
//遍历当前数组中每个元素
for(var i=0;i<this.length;i++){
//如果当前元素不是undefined
if(this[i]!==undefined){//判断稀疏数组
//调用fun传入当前元素值,位置i,当前数组,将结果保存在r中
//将newArr的i位置赋值为r
var r=fun(this[i],i,this);
newArr[i]=r;
}
}//(遍历结束)
return newArr;//返回newArr
}
} - 如果浏览器不支持reduce属性,reduce的实现原理
if(Array.prototype.reduce===undefined){
Array.prototype.reduce=function(fun,base){
base===undefined&&(base=0);
for(var i=0;i<this.length;i++){
if(this[i]!==undefined){
base=fun(base,this[i],i,this);
}
}
return base;
}
} - 如果浏览器不支持bind属性, bind函数的实现原理
if(Function.prototype.bind===undefined){
Function.prototype.bind=function(obj/*,参数列表*/){
var fun=this;//留住this
//*****将类数组对象,转化为普通数组
var args=Array.prototype.slice.call(arguments,1);
//args保存的就是提前绑定的参数列表
/*function slice(1){
var sub=[];
for(var i=0;i<length;i++){
sub.push(arguments[i]);
}
return sub;
}*/
return function(){
//将后传入的参数值,转为普通数组
var innerArgs=Array.prototype.slice.call(arguments);//将之前绑定的参数值和新传入的参数值,拼接为完整参数之列表
var allArgs=args.concat(innerArgs)
//调用原始函数fun,替换this为obj,传入所有参数
fun.apply(obj,allArgs);
}
}
}
前端javascript知识(三)的更多相关文章
- Javascript知识三
O(∩_∩)O...今天继续学习了Javascript的知识,下面就总结一下. 数组: 判断是否为数组(instanceof Array) 在JavaScript中,数组不一定是同一类型 var ar ...
- 前端javascript知识(二)
documen.write和 innerHTML的区别 document.write只能重绘整个页面 innerHTML可以重绘页面的一部分 浏览器检测通过什么? (1) navigator.user ...
- 前端javascript知识(一)
介绍一下 JS 的基本数据类型. Undefined.Null.Boolean.Number.String 介绍一下 JS 有哪些内置对象. Object 是 JavaScript 中所有对象的父对象 ...
- Javascript知识四(DOM)
[箴 10:4] 手懒的,要受贫穷:手勤的,却要富足. He becometh poor that dealeth with a slack hand: but the hand of the di ...
- 【原文】前端程序员必须知道的高性能Javascript知识
原文:前端程序员必须知道的高性能Javascript知识 想必大家都知道,JavaScrip是全栈开发语言,浏览器,手机,服务器端都可以看到JS的身影. 本文会分享一些高效的JavaScript的最佳 ...
- 前端学习 第三弹: JavaScript语言的特性与发展
前端学习 第三弹: JavaScript语言的特性与发展 javascript的缺点 1.没有命名空间,没有多文件的规范,同名函数相互覆盖 导致js的模块化很差 2.标准库很小 3.null和unde ...
- 前端笔记知识点整合之JavaScript(三)关于条件判断语句、循环语句那点事
一.条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句. JS中有三种语法是可以表示条件分支的 1.1 if……else…… 条件分支的主力语法,这个主力 ...
- 快速掌握JavaScript面试基础知识(三)
译者按: 总结了大量JavaScript基本知识点,很有用! 原文: The Definitive JavaScript Handbook for your next developer interv ...
- web前端基础知识及快速入门指南
web前端基础知识及快速入门指南 做前端开发有几个月了,虽然说是几个月,但是中间断断续续的上课.考试以及其它杂七杂八的事情,到现在居然一直感觉自己虽然很多前端的知识很眼熟,却也感觉自己貌似也知识在门口 ...
随机推荐
- Datagridview 实现二维表头和行合并
借鉴别人的,改了改,没用timer using System;using System.Collections.Generic;using System.ComponentModel;using Sy ...
- Django实现注册,往邮箱发送验证链接
由于最近要做个平台,在GitHub上下载了一个系统框架,想着为了安全,实现注册时往一个邮箱发送注册信息,由管理员来确认是否同意其注册. 感谢博主:https://blog.csdn.net/geek_ ...
- 牛客-DongDong数颜色 及其相似题
大佬博客 ps:在牛客上做到这题不会,学会之后补了两道相关题.顺便记录一下. 牛客-DongDong数颜色 sol:dfs序+莫队,先把树上的点标上dfs序,因为子树的dfs序是连续的,所以子树可以表 ...
- 项目中spring容器加载的问题
今天做一个项目采用的是传统架构,没有采用分布式,部署时出现了异常,信息是: org.springframework.beans.factory.NoSuchBeanDefinitionExceptio ...
- C++对数组进行复制
C++ 风格的复制操作 使用STL中的copy算法 int a[] = {1,2,3,4,5}; int b[5]; std::copy(std::begin(a),std::end(a),std:: ...
- Nginx 原理和架构
Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器.Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名Nginx 里 ...
- 关于HTTP请求GET和POST的区别
1.GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头<request-line>中),以?分割URL和传输数据,多个参数用&连接;例如:login.actio ...
- <USACO06NOV>玉米田Corn Fields
状压emm 二进制真有趣 来自dp垃圾的欣喜 Description 农民 John 购买了一处肥沃的矩形牧场,分成M*N(1 <= M <= 12; 1 <= N <= 12 ...
- <USACO09DEC>过路费Cow Toll Pathsの思路
啊好气 在洛谷上A了之后 隔壁jzoj总wa 迷茫了很久.发现那题要文件输入输出 生气 肥肠不爽 Description 跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦 ...
- Java Servlet和Java Filter简介
一:简介servlet 1.什么是Servlet? Servlet可以通过多种方式进行描述,具体取决于上下文: (1)Servlet是一种用于创建web应用程序的技术 (2)Servlet是一个API ...