js&jq面试笔记,该部分为下部分。javascript
如:'hello' -> 'h e l l o' function joinSpace(str){ return str.split('').join(' ') }
方法1 function isString(obj){ return typeof(obj) === "string"? true: false; // returntypeof obj === "string"? true: false; } 方法2 function isString(obj){ return obj.constructor === String? true: false; } 方法3 function isString(obj){ return Object.prototype.toString.call(obj) === "[object String]"?true:false; } 如: var isstring = isString('xiaoming'); console.log(isstring); // true
方法一:使用replace正则匹配的方法 去除全部空格: str = str.replace(/\s*/g,""); 去除两头空格: str = str.replace(/^\s*|\s*$/g,""); 去除左空格: str = str.replace( /^\s*/, “”); 去除右空格: str = str.replace(/(\s*$)/g, ""); str为要去除空格的字符串,实例以下: var str = " 23 23 "; var str2 = str.replace(/\s*/g,""); console.log(str2); // 2323 方法二:使用str.trim()方法 str.trim() //局限性:没法去除中间的空格,实例以下: var str = " xiao ming "; var str2 = str.trim(); console.log(str2); //xiao ming 同理: str.trimLeft(),str.trimRight() //分别用于去除字符串左右空格。 方法三:使用jquery,$.trim(str)方法 $.trim(str) 局限性:没法去除中间的空格,实例以下: var str = " xiao ming "; var str2 = $.trim(str) console.log(str2); // xiao ming
//测试地址为:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23 function showWindowHref(){ var sHref = window.location.href; var args = sHref.split('?'); if(args[0] == sHref){ return ""; } var arr = args[1].split('&'); var obj = {}; for(var i = 0;i< arr.length;i++){ var arg = arr[i].split('='); obj[arg[0]] = arg[1]; } return obj; } var href = showWindowHref(); // obj console.log(href['name']); // xiaoming
//这里只是列举了经常使用的字符串函数,具体使用方法,请参考网址。 concat() 将两个或多个字符的文本组合起来,返回一个新的字符串。 indexOf() 返回字符串中一个子串第一处出现的索引。若是没有匹配项,返回 -1 。 charAt() 返回指定位置的字符。 lastIndexOf() 返回字符串中一个子串最后一处出现的索引,若是没有匹配项,返回 -1 。 match() 检查一个字符串是否匹配一个正则表达式。 substr() 返回从string的startPos位置,长度为length的字符串 substring() 返回字符串的一个子串。传入参数是起始位置和结束位置。 slice() 提取字符串的一部分,并返回一个新字符串。 replace() 用来查找匹配一个正则表达式的字符串,而后使用新字符串代替匹配的字符串。 search() 执行一个正则表达式匹配查找。若是查找成功,返回字符串中匹配的索引值。不然返回 -1 。 split() 经过将字符串划分红子串,将一个字符串作成一个字符串数组。 length 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。 toLowerCase() 将整个字符串转成小写字母。 toUpperCase() 将整个字符串转成大写字母。
var str = 'asdfssaaasasasasaa'; var json = {}; for (var i = 0; i < str.length; i++) { if(!json[str.charAt(i)]){ //判断json中是否存在当前str.charAr(i)的值 json[str.charAt(i)] = 1; //若是不存在,则将其存放在json中,而且赋值为1,至关于出现的次数为1 }else{ json[str.charAt(i)]++; //若是存在,则这个字符的值加1,至关于次数加1 } }; var iMax = 0; var iIndex = ''; for(var i in json){ if(json[i]>iMax){ //判断当前json中的键值(至关于当前键所在字符的次数)是否大于iMax iMax = json[i]; iIndex = i; } } console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'次');
constructor 返回对建立此对象的数组函数的引用。 var test=new Array(); if (test.constructor==Array){ document.write("This is an Array"); } length 设置或返回数组中元素的数目。 prototype 使您有能力向对象添加属性和方法。
join() 把数组的全部元素放入一个字符串。元素经过指定的分隔符进行分隔。 var arr = ['xiao','lin','qiqi','mingtian']; var arr2 = arr.join(','); console.log(arr2); // 根据','隔开返回的字符串为:"xiao,lin,qiqi,mingtian" pop() 删除并返回数组的最后一个元素。 var arr = [2,3,4,5]; var arr2 = arr.pop(); console.log(arr2); // 删除的数组的最后一个元素为:5 console.log(arr); // 删除元素以后的数组为:[2, 3, 4] shift() 删除并返回数组的第一个元素 var arr = [2,3,4,5]; var arr2 = arr.shift(); console.log(arr2); // 删除的数组的第一个元素为:2 console.log(arr); // 删除元素以后的数组为:[3, 4,5] push() 向数组的末尾添加一个或更多元素,并返回新的长度。 var arr = [2,3,4,5]; var arr2 = arr.push(6); console.log(arr2); // 返回的数组长度:5 console.log(arr); // [2, 3, 4, 5, 6] unshift() 向数组的开头添加一个或更多元素,并返回新的长度。 var arr = ['xiao','ming','qiqi','aiming']; var arr1 = arr.unshift('lang'); console.log(arr1); // 返回的数组的长度: 5 console.log(arr); //向数组开头添加元素返回的结果:["lang", "xiao", "ming", "qiqi", "aiming"] reverse() 颠倒数组中元素的顺序。 var arr = [2,3,4,5]; arr.reverse(); console.log(arr); // [5, 4, 3, 2] slice() 从某个已有的数组返回选定的元素 var arr = [2,3,4,5]; var arr2 = arr.slice(1,3); console.log(arr2); // 截取区间返回的数组为:[3, 4] console.log(arr); // [2, 3, 4, 5] sort() 对数组的元素进行排序 借助排序函数,实现数值由小到大排序 function sortNumber(a,b){ return a - b } var arr = [23,30,42,5]; var arr2 = arr.sort(sortNumber); console.log(arr2); // [5, 23, 30, 42] console.log(arr); // [5, 23, 30, 42] 借助排序函数,实现数值由大到小排序 function sortNumber(a,b){ return b - a } var arr = [23,30,42,5]; var arr2 = arr.sort(sortNumber); console.log(arr2); // [42, 30, 23, 5] console.log(arr); // [42, 30, 23, 5] splice() 删除元素,并向数组添加新元素。 语法:arrayObject.splice(index,howmany,item1,.....,itemX) index:必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 howmany:必需。要删除的项目数量。若是设置为 0,则不会删除项目。 item1, ..., itemX:可选。向数组添加的新项目。 // 建立一个新数组,并向其添加一个元素 var arr = [1,2,3,4]; arr.splice(2,0,5); console.log(arr); // [1, 2, 5, 3, 4] // 删除位于 index 2 的元素,并添加一个新元素来替代被删除的元素: var arr = [1,2,3,4]; arr.splice(2,1,5); console.log(arr); // [1, 2, 5, 4] toString() 把数组转换为字符串,并返回结果。 var arr = ['xiao','ming','qiqi','aiming']; arr.toString(); console.log(arr); // ["xiao", "ming", "qiqi", "aiming"]
方法一 var arr = [0,2,3,4,4,0,2]; var obj = {}; var tmp = []; for(var i = 0 ;i< arr.length;i++){ if( !obj[arr[i]] ){ obj[arr[i]] = 1; tmp.push(arr[i]); } } console.log(tmp); //结果以下: [0, 2, 3, 4] 方法二 var arr = [2,3,4,4,5,2,3,6]; var arr2 = []; for(var i = 0;i< arr.length;i++){ if(arr2.indexOf(arr[i]) < 0){ arr2.push(arr[i]); } } console.log(arr2); //结果为:[2, 3, 4, 5, 6] 方法三 var arr = [2,3,4,4,5,2,3,6]; var arr2 = arr.filter(function(element,index,self){ return self.indexOf(element) === index; }); console.log(arr2); //结果为:[2, 3, 4, 5, 6] 方法四:(ES6提供了新的数据结构 Set) let unique= [...new Set(array)]; let unique= [...new Set([2,3,4,4,5,2,3,6])]; console.log(unique)
求数组最大值:Math.max.apply(null,arr); var arr = [3,43,23,45,65,90]; var max = Math.max.apply(null,arr); console.log(max); // 90 求数组最小值:Math.min.apply(null,arr); var arr = [3,43,23,45,65,90]; var min = Math.min.apply(null,arr); console.log(min); // 3
选择排序 /** *以一个角标的元素和其余元素进行比较。 *在内循环第一次结束,最值出现的头角标位置上。 */ function selectSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { var len = array.length, temp; for (var i = 0; i < len - 1; i++) { //轮数 var min = array[i]; for (var j = i + 1; j < len; j++) { //第一个与第二个比较 if (array[j] < array[i]) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } return array; } else { return 'array is not an Array!'; } } 冒泡排序 /** *比较方式:相邻两个元素进行比较,若是后一个比前一个小,换位置。 *原理:内循环结束一次,最值出如今尾角标位置。 */ function bubbleSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { var len = array.length, temp; for(var j=0;j<len-1;j++){ //两两比较,若是前一个比后一个大,则交换位置。 for(var i=0;i<len-1-j;i++){ //-i:让每次参与比较的元素减小。-1:避免角标越界。 if(arr[i]>arr[i+1]){ var temp = arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; } } } return array; } else { return 'array is not an Array!'; } } 二分插入排序 /** *为了提升查找效率,可以使用折半查找的方式,注意:这种查找只对有序的数组有效。这种方式也叫二分查找法。 */ function binaryInsertionSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { for (var i = 1; i < array.length; i++) { var key = array[i], left = 0, right = i - 1; while (left <= right) { var middle = parseInt((left + right) / 2); if (key < array[middle]) { right = middle - 1; } else { left = middle + 1; } } for (var j = i - 1; j >= left; j--) { array[j + 1] = array[j]; } array[left] = key; } return array; } else { return 'array is not an Array!'; } }
方法一: var arr = [1,2,3,4]; var arr2 = []; while(arr.length) { var num = arr.pop(); //删除数组最后一个元素并返回被删除的元素 arr2.push(num); } console.log(arr2); // [4, 3, 2, 1] 方法二: var arr = [1,2,3,4]; var arr2 = []; while(arr.length){ var num = arr.shift(); //删除数组第一个元素并返回被删除的元素 arr2.unshift(num); } console.log(arr2);
典型的是函数的argument参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。css
a.使用Array.prototype.slice.call(); Array.prototype.slice.call({ 0:"likeke", 1:12, 2:true, length:3 }); //["likeke", 12, true] b.使用[].slice.call(),了解js原型链的都知道,实际上这种方法和第一中方法是同样的,但上面第一种方式相对效率更高。 [].slice.call({ 0:"likeke", 1:12, 2:true, length:3 }); //["likeke", 12, true] c. 使用ES6中Array.from方法; Array.from({ 0:"lk", 1:12, 2:2013, 3:"长安大学", length:4 }); //["lk", 12, 2013, "长安大学"]
var obj = {name: 'wan',age: 20, sex: 'male'}; var objKey = []; for(var item in obj){ if(obj.hasOwnProperty(item)){ objKey.push(item); } } //for(var item in obj){ // objKey.push(item); //} console.log(objKey);//["name", "age", "sex"]
func.call(thisObj,a,b,c...) || func.apply(thisObj,array)
obj.call(thisObj,a,b,c...) || obj.apply(thisObj,array)
区别:call的参数个数,从第二个开始 大于等于 0个,为单个变量;apply的参数只有两个,第二个参数为一个数组,即array = [a,b,c...];html
实例一:借调方法,对象sub借调对象add的方法add(函数也是对象) function add(a,b){return a+b} function sub(a,b){return a-b} add.call(sub,3,1)//4 sub.call(add,3,1)//2 add.call(sub,3,1) === add(3,1) 实例二:改变this指向 function a(){console.log(this)} var obj = {} a()//window a.call()//window a.call(obj)//obj 实例三:实现继承 function Animal(name){this.name=name;this.showName=function(){alert(this.name)}} function Cat(name){ Animal.call(this,name); //将Animal对象的属性和方法应用到Cat上,所以Cat继承了Animal的全部属性和方法 } var cat = new Cat(“Black Cat”); cat.showName(); //Black Cat 实例四:多重继承 function add(a,b){return a+b} function sub(a,b){return a-b} function calc(a,b){ add.call(this) sub.call(this) }
call、apply、bind,this老是指向调用它的对象
var A = function(){} A.prototype.method1 = function(a,b){return a+b}
function Parent(){ this.surname = 'wan'; this.work = function(){console.log('i like work')} } function Child(){} 原型链继承:Child.prototype = new Parent() 实例化:let person = new Child(); console.log(person.surname);//wan person.work();//i like work 构造函数继承:function Child(){Parent.call(this)} 组合继承: function Child(){ Parent.call(this);//继承属性 } Child.prototype = new Parent();//继承方法 原型式继承: function object(obj){ function Func(){}; Func.prototype = obj; return new Func(); } var Child = object(Parent); 寄生式继承: 寄生组合式继承:
function Person(){ var sex = 'man';//var 私有 this.surnname = 'wan';//this 公有 }
(Object.prototype.toString.call()方法及应用) /** * 对象克隆 * 支持基本数据类型及对象 * 递归方法 */ function clone(obj) { var o; switch (typeof obj) { case "undefined": break; case "string": o = obj + ""; break; case "number": o = obj - 0; break; case "boolean": o = obj; break; case "object": // object 分为两种状况 对象(Object)或数组(Array) if (obj === null) { o = null; } else { if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") { o = []; for (var i = 0; i < obj.length; i++) { o.push(clone(obj[i])); } } else { o = {}; for (var k in obj) { o[k] = clone(obj[k]); } } } break; default: o = obj; break; } return o; } //测试 var a=[12,34,'123']; console.log(clone(a)); var b=null; console.log(clone(b)); var c={1:'a',2:'b',3:'c'}; console.log(clone(c)); var d=1; console.log(clone(d));
一、工厂模式 function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.getName = function () { return this.name; } return o;//使用return返回生成的对象实例 } var person = createPerson('Jack', 19, 'SoftWare Engineer'); 建立对象交给一个工厂方法来实现,能够传递参数,但主要缺点是没法识别对象类型,由于建立对象都是使用Object的原生构造函数来完成的。 二、构造函数模式 function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = function () { return this.name; } } var person1 = new Person('Jack', 19, 'SoftWare Engineer'); var person2 = new Person('Liye', 23, 'Mechanical Engineer'); 使用自定义的构造函数(与普通函数同样,只是用它来建立对象),定义对象类型(如:Person)的属性和方法。它与工厂方法区别在于: 没有显式地建立对象,直接将属性和方法赋值给this对象;没有return语句; 此外,要建立Person的实例,必须使用new关键字,以Person函数为构造函数,传递参数完成对象建立;实际建立通过如下4个过程: 建立一个对象 将函数的做用域赋给新对象(所以this指向这个新对象,如:person1) 执行构造函数的代码 返回该对象 上述由Person构造函数生成的两个对象person1与person2都是Person的实例,所以可使用instanceof判断,而且由于全部对象都继承Object,所以person1 instanceof Object也返回真: alert(person1 instanceof Person);//true; alert(person2 instanceof Person);//true; alert(person1 instanceof Object);//true; alert(person1.constructor === person2.constructor);//ture; 虽然构造函数方式比较不错,但也存在缺点,那就是在建立对象时,特别针对对象的属性指向函数时,会重复的建立函数实例,以上述代码为基础,能够改写为: function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = new Function () {//改写后效果与原代码相同,不过是为了方便理解 return this.name; } } 上述代码,建立多个实例时,会重复调用new Function();建立多个函数实例,这些函数实例还不是一个做用域中,固然这通常不会有错,但这会形成内存浪费。 固然,能够在函数中定义一个getName = getName的引用,而getName函数在Person外定义,这样能够解决重复建立函数实例问题,但在效果上并无起到封装的效果,以下所示: function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.getName = getName; } function getName() {//处处是代码,看着乱!! return this.name; } 三、原型模式 JS每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,它是全部经过new操做符使用函数建立的实例的原型对象。 原型对象最大特色是,全部对象实例共享它所包含的属性和方法,也就是说,全部在原型对象中建立的属性或方法都直接被全部对象实例共享。 function Person(){} Person.prototype.name = 'Jack';//使用原型来添加属性 Person.prototype.age = 29; Person.prototype.getName = function(){ return this.name; } var person1 = new Person(); alert(person1.getName());//Jack var person2 = new Person(); alert(person1.getName === person2.getName);//true;共享一个原型对象的方法 原型是指向原型对象的,这个原型对象与构造函数没有太大关系,惟一的关系是函数的prototype是指向这个原型对象!而基于构造函数建立的对象实例也包含一个内部指针为:[[prototype]]指向原型对象。 实例属性或方法的访问过程是一次搜索过程: 首先从对象实例自己开始,若是找到属性就直接返回该属性值; 若是实例自己不存在要查找属性,就继续搜索指针指向的原型对象,在其中查找给定名字的属性,若是有就返回; 基于以上分析,原型模式建立的对象实例,其属性是共享原型对象的;但也能够本身实例中再进行定义,在查找时,就不从原型对象获取,而是根据搜索原则,获得本实例的返回;简单来讲,就是实例中属性会屏蔽原型对象中的属性; 原型与in操做符 一句话:不管原型中属性,仍是对象实例的属性,均可以使用in操做符访问到;要想判断是不是实例自己的属性可使用object.hasOwnProperty(‘attr’)来判断; 原生对象中原型 原生对象中原型与普通对象的原型同样,能够添加/修改属性或方法,如如下代码为全部字符串对象添加去左右空白原型方法: String.prototype.trim = function(){ return this.replace(/^\s+/,'').replace(/\s+$/,''); } var str = ' word space '; alert('!'+str.trim()+'!');//!word space! 原型模式的缺点,它省略了为构造函数传递初始化参数,这在必定程序带来不便;另外,最主要是当对象的属性是引用类型时,它的值是不变的,老是引用同一个外部对象,全部实例对该对象的操做都会其它实例: function Person() { } Person.prototype.name = 'Jack'; Person.prototype.lessons = ['Math','Physics']; var person1 = new Person(); person1.lessons.push('Biology'); var person2 = new Person(); alert(person2.lessons);//Math,Physics,Biology,person1修改影响了person2 四、组合构造函数及原型模式 目前最为经常使用的定义类型方式,是组合构造函数模式与原型模式。构造函数模式用于定义实例的属性,而原型模式用于定义方法和共享的属性。结果,每一个实例都会有本身的一份实例属性的副本,但同时又共享着对方方法的引用,最大限度的节约内存。此外,组合模式还支持向构造函数传递参数,可谓是集两家之所长。 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.lessons = ['Math', 'Physics']; } Person.prototype = { constructor: Person,//原型字面量方式会将对象的constructor变为Object,此外强制指回Person getName: function () { return this.name; } } var person1 = new Person('Jack', 19, 'SoftWare Engneer'); person1.lessons.push('Biology'); var person2 = new Person('Lily', 39, 'Mechanical Engneer'); alert(person1.lessons);//Math,Physics,Biology alert(person2.lessons);//Math,Physics alert(person1.getName === person2.getName);//true,//共享原型中定义方法 在所接触的JS库中,jQuery类型的封装就是使用组合模式来实例的!!! 五、动态原型模式 组合模式中实例属性与共享方法(由原型定义)是分离的,这与纯面向对象语言不太一致;动态原型模式将全部构造信息都封装在构造函数中,又保持了组合的优势。 其原理就是经过判断构造函数的原型中是否已经定义了共享的方法或属性,若是没有则定义,不然再也不执行定义过程。该方式只原型上方法或属性只定义一次,且将全部构造过程都封装在构造函数中,对原型所作的修改能当即体现全部实例中: function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.lessons = ['Math', 'Physics']; } if (typeof this.getName != 'function') {//经过判断实例封装 Person.prototype = { constructor: Person,//原型字面量方式会将对象的constructor变为Object,此外强制指回Person getName: function () { return this.name; } } } var person1 = new Person('Jack', 19, 'SoftWare Engneer'); person1.lessons.push('Biology'); var person2 = new Person('Lily', 39, 'Mechanical Engneer'); alert(person1.lessons);//Math,Physics,Biology alert(person2.lessons);//Math,Physics alert(person1.getName === person2.getName);//true,//共享原型中定义方法
.click(function(){}) .bind({'click mouseleave',function(){}},{'click mouseleave',function(){}}) //在.bind()绑定事件的时候,这些元素必须已经存在。 .on() //为动态绑定事件 .one("click", function() {alert("This will be displayed only once.");});//绑定一个事件,而且只运行一次,而后删除本身,
$()
是什么? $()
函数是 jQuery() 函数的别称。$()
函数用于将任何对象包裹成 jQuery 对象,接着你就被容许调用定义在 jQuery 对象上的多个不一样方法。前端
能够将一个选择器字符串传入` $()` 函数,它会返回一个包含全部匹配的 DOM 元素数组的 jQuery 对象。
$('[name=selectname] :selected')
$(this)
和 this
关键字在 jQuery 中有何不一样?而 this 表明当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如 $(this)。java
得到a标签的onclick属性: $("a").attr("onclick") 删除onclick属性:$("a").removeAttr("onclick"); 设置onclick属性:$("a").attr("onclick","test();");
$(selector).addClass(class):为每一个匹配的元素添加指定的类名 $(selector).removeClass(class):从全部匹配的元素中删除所有或者指定的类,删除class中某个值; $(selector).toggleClass(class):若是存在(不存在)就删除(添加)一个类 $(selector).removeAttr(class);删除class这个属性;
(1)、基本选择器:#id,class,element,*; (2)、层次选择器:parent > child,prev + next ,prev ~ siblings (3)、基本过滤器选择器::first,:last ,:not ,:even ,:odd ,:eq ,:gt ,:lt (4)、内容过滤器选择器: :contains ,:empty ,:has ,:parent (5)、可见性过滤器选择器::hidden ,:visible (6)、属性过滤器选择器:[attribute] ,[attribute=value] ,[attribute!=value] ,[attribute^=value] ,[attribute$=value] ,[attribute*=value] (7)、子元素过滤器选择器::nth-child ,:first-child ,:last-child ,:only-child (8)、表单选择器: :input ,:text ,:password ,:radio ,:checkbox ,:submit 等; (9)、表单过滤器选择器::enabled ,:disabled ,:checked ,:selected
delegate()会在如下两个状况下使用到:jquery
一、若是你有一个父元素,须要给其下的子元素添加事件,这时你可使用delegate()了,代码以下:css3
`$("ul").delegate("li", "click", function(){ $(this).hide(); });`
二、当元素在当前页面中不可用时,可使用delegate()web
(1)、window.onload 方法是在网页中全部的元素(包括元素的全部关联文件)彻底加载到浏览器后才执行的。 (2)、$(document).ready() 方法能够在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。
$(document).ready(function() { window.history.forward(1); //OR window.history.forward(-1); });
$.get()
提交和$.post()
提交有区别吗?一、请求方式不一样:$.get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的。面试
二、参数传递方式不一样:get请求会将参数跟在URL后进行传递,而POST请求则是做为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。ajax
三、数据传输大小不一样:get方式传输的数据大小不能超过2KB 而POST要大的多
四、安全问题: GET 方式请求的数据会被浏览器缓存起来,所以有安全问题。
$.ajax({ url:'http://www.baidu.com', type:'POST', data:data, cache:true, headers:{}, beforeSend:function(){}, success:function(){}, error:function(){}, complete:function(){} });
(1)、bind 【jQuery 1.3以前】
定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数; 语法:bind(type,[data],function(eventObject)); 特色: (1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给将来新增的元素绑定事件。 (2)、当页面加载完的时候,你才能够进行bind(),因此可能产生效率问题。 实例以下:$( "#members li a" ).bind( "click", function( e ) {} );
(2)、live 【jQuery 1.3以后】
定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数; 语法:live(type, [data], fn); 特色: (1)、live方法并无将监听器绑定到本身(this)身上,而是绑定到了this.context上了。 (2)、live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素没必要再绑定一次监听器。 (3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即$(“ul”").live...能够,但$("body").find("ul").live...不行; 实例以下:$( document ).live( "click", "#members li a", function( e ) {} );
(3)、delegate 【jQuery 1.4.2中引入】
定义和用法:将监听事件绑定在就近的父级元素上 语法:delegate(selector,type,[data],fn) 特色: (1)、选择就近的父级元素,由于事件能够更快的冒泡上去,可以在第一时间进行处理。 (2)、更精确的小范围使用事件代理,性能优于.live()。能够用在动态添加的元素上。 实例以下: $("#info_table").delegate("td","click",function(){/*显示更多信息*/}); $("table").find("#info").delegate("td","click",function(){/*显示更多信息*/});
(4)、on 【1.7版本整合了以前的三种方式的新事件绑定机制】
定义和用法:将监听事件绑定到指定元素上。 语法:on(type,[selector],[data],fn) 实例以下:$("#info_table").on("click","td",function(){/*显示更多信息*/});参数的位置写法与delegate不同。 说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。 总结:.bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()
命名空间 封闭空间 js模块化mvc(数据层、表现层、控制层) seajs 变量转换成对象的属性 对象化
压缩css、js文件 合并js、css文件,减小http请求 外部js、css文件放在最底下 减小dom操做,尽量用变量替代没必要要的dom操做
内容方面:
1.减小 HTTP 请求 (Make Fewer HTTP Requests) 2.减小 DOM 元素数量 (Reduce the Number of DOM Elements) 3.使得 Ajax 可缓存 (Make Ajax Cacheable)
针对CSS:
1.把 CSS 放到代码页上端 (Put Stylesheets at the Top) 2.从页面中剥离 JavaScript 与 CSS (Make JavaScript and CSS External) 3.精简 JavaScript 与 CSS (Minify JavaScript and CSS) 4.避免 CSS 表达式 (Avoid CSS Expressions)
针对JavaScript :
1. 脚本放到 HTML 代码页底部 (Put Scripts at the Bottom) 2. 从页面中剥离 JavaScript 与 CSS (Make JavaScript and CSS External) 3. 精简 JavaScript 与 CSS (Minify JavaScript and CSS) 4. 移除重复脚本 (Remove Duplicate Scripts)
面向图片(Image):
1.优化图片 2 不要在 HTML 中使用缩放图片 3 使用恰当的图片格式 4 使用 CSS Sprites 技巧对图片优化
优化图像:
一、不用图片,尽可能用css3代替。 好比说要实现修饰效果,如半透明、边框、圆角、阴影、渐变等,在当前主流浏览器中均可以用CSS达成。 二、 使用矢量图SVG替代位图。对于绝大多数图案、图标等,矢量图更小,且可缩放而无需生成多套图。如今主流浏览器都支持SVG了,因此可放心使用! 3.、使用恰当的图片格式。咱们常见的图片格式有JPEG、GIF、PNG。 基本上,内容图片多为照片之类的,适用于JPEG。 而修饰图片一般更适合用无损压缩的PNG。 GIF基本上除了GIF动画外不要使用。且动画的话,也更建议用video元素和视频格式,或用SVG动画取代。 四、按照HTTP协议设置合理的缓存。 五、使用字体图标webfont、CSS Sprites等。 六、用CSS或JavaScript实现预加载。 七、WebP图片格式能给前端带来的优化。WebP支持无损、有损压缩,动态、静态图片,压缩比率优于GIF、JPEG、JPEG2000、PG等格式,很是适合用于网络等图片传输。
图像格式的区别:
矢量图:图标字体,如 font-awesome;svg 位图:gif,jpg(jpeg),png
区别:
1 、gif:是是一种无损,8位图片格式。具备支持动画,索引透明,压缩等特性。适用于作色彩简单(色调少)的图片,如logo,各类小图标icons等。 二、JPEG格式是一种大小与质量相平衡的压缩图片格式。适用于容许轻微失真的色彩丰富的照片,不适合作色彩简单(色调少)的图片,如logo,各类小图标icons等。 三、png:PNG能够细分为三种格式:PNG8,PNG24,PNG32。后面的数字表明这种PNG格式最多能够索引和存储的颜色值。 关于透明:PNG8支持索引透明和alpha透明;PNG24不支持透明;而PNG32在24位的PNG基础上增长了8位(256阶)的alpha通道透明;
优缺点:
一、能在保证最不失真的状况下尽量压缩图像文件的大小。 二、对于须要高保真的较复杂的图像,PNG虽然能无损压缩,但图片文件较大,不适合应用在Web页面上。
ES5的类 function Person(name) { this.name = name; } Person.prototype.sayHello = function(){ return 'Hi, I am ' + this.name; } ES6的类 class Person { constructor(name){ this.name = name; } sayHello(){ return 'Hi, I am ' + this.name; } } typeof Person; //'function' 调用的方式都是一致的: var me = new Person('Yecao');
ES6继承 class Father{ constructor(name){ this.name = name; } getName(){ console.log(this.name); } // 这里是父类的f方法 f(){ console.log('fffffffffffffffffffffff'); } } class Son extends Father{ constructor(name,age){ super(name); // HACK: 这里super()要在第一行 this.age = age; } getAge(){ console.log(this.age); } // 子类的f方法 f(){ console.log('sssssssssssssssssssssss'); } } var s1 = new Son('张一',12); s1.getName(); s1.getAge(); console.log(s1.__proto__); // 为Son,不用修正 s1.f(); // 打印ssssssssssssss s1.__proto__ = new Father(); // 改变s1的原型指向,改成Father s1.f(); // 打印ffffffffffffff console.log(s1.__proto__); // 为Father ES5继承 function Father(name){ this.name = name; } function Son(name,age){ Father.call(this,name); this.age = age; } Father.prototype.getName = function(){ console.log(this.name); } // 这里注意原型继承要在,实例化s1变量以前,若是要使用原型链上的方法的话,子类的原型是父类的一个实例 Son.prototype = new Father; // 修正构造器,这里注意要将Son的构造器指向赋值为Son,不然,打印出来的s1是Father对象 Son.prototype.constructor = Son; Son.prototype.getAge = function(){ console.log(this.age); } var s1 = new Son('李四',22); console.log(s1); // Son {name:'李四',age:22} s1.getName(); // 李四 console.log(Son.prototype.constructor); // Son console.log(s1.constructor); // Son,若是不纠正,则为Father s1.getAge(); // 22 //HACK:这里经过__proto__这个s1实例的属性找到了Son的prototype,并为其添加了say的方法 s1.__proto__.say = function(){ console.log('hhhhhhhhhhhhhhhhhhhhhhhh'); } s1.say() // 打印 hhhhhhhhhhhhhhh // NOTE: __proto__这个属性是具体到某个实例化后的对象才有的属性,指向他所属的类的原型 console.log(new Son().__proto__); // 为Son对象
Map和Set都叫作集合,可是他们也有所不一样。Set常被用来检查对象中是否存在某个键名,Map集合常被用来获取已存的信息。
四个操做方法。 add(value):添加某个值,返回Set结构自己。 delete(value):删除某个值,返回一个布尔值,表示删除是否成功。 has(value):返回一个布尔值,表示该值是否为Set的成员。 clear():清除全部成员,没有返回值。 Set 结构的实例有四个遍历方法,能够用于遍历成员。 keys():返回键名的遍历器 values():返回键值的遍历器 entries():返回键值对的遍历器 forEach():使用回调函数遍历每一个成员
它相似于对象,也是键值对的集合,可是“键”的范围不限于字符串,各类类型的值(包括对象)均可以看成键。
Map有size()属性,查看Map对象大小,set(key , value) , get(Key), delete(key) , has(key) ,clear()方法。
Map 结构原生提供三个遍历器生成函数和一个遍历方法。 keys():返回键名的遍历器。 values():返回键值的遍历器。 entries():返回全部成员的遍历器。 forEach():遍历 Map 的全部成员。