- Javascript有哪些打开一个页面的方式?
1.超链接<a href="http://www.100sucai.com/" title="100素材网">Welcome</a>
等效于js代码
window.location.href="http://www.100sucai.com/"; //在同当前窗口中打开窗口
2.超链接<a href="http://www.100sucai.com/" title="100素材网" target="_blank">Welcome</a>
等效于js代码
window.open("http://www.100sucai.com/");//在另外新建窗口中打开窗口
window.history.back(-1);返回上一页
window.open(sURL [,vArguments] [,sFeatures]) 新页面
window. showmodaldialog(sURL[, vArguments] [,sFeatures]) 模态对话框
window.showModelessDialog(sURL[, vArguments] [,sFeatures]) 非模态对话框
- Javascript如何做到在子页面中调用父页面的js函数或者全局变量(如test()函数,test()变量)?
window.opener.test();Window.opener.test = “abc”;
2.1 window.parent与window.opener的区别?
有这样一个需求,弹出一个新窗口 并从该新页面的select选择框中选择需要的类别,再返回到之前的父窗口页面的某个文本框中。这里就要用到window.parent和window.opener如题两种方法都是javascript调用父窗口的方法。1、window.parent是iframe页面调用父窗口对象比如:parent.jsp里面有一个文本框当要在children.jsp里为parent.jsp页面中的username文本框赋值时,可在children.jsp里这样写:window.parent.document.getElementById("username").value = "hello"对应jquery版本为:$("#username",window.parent.document).val("hello");2、window.opener是window.open打开的子页面调用父页面对象比如a.jspfunction show(){ window.open( "PLUGIN/CMS/shop/b.jsp", "ModifyAcce",'width=500,height=400,toolbar=no,status=no,location=no,scrollbars=yes,resizable=yes'); }想要在b.jsp里为a.jsp中的myhobby赋值,可以这样写:window.opener.document.getElementById("myhobby").value = "hello";对应jquery版本为:$("#myhobby",window.opener.document).val("hello");总结:window.parent中的parent表示父窗口,比如一个A页面利用iframe或frame调用B页面,那么A页面就是B页面的parent。B页面可以通过parent访问A页面。window.opener中的opener表示谁打开我的,比如一个A页面利用window.open弹出了B页面,那么A页面就是B页面的opener。B页面可以通过opener访问A页面。
- Javascript中定时执行如何实现?
setTimeout();定时执行,执行一次。clearTimeout(定时器对象名)结束setInterval();定时执行,一直执行。clearInterval(定时器对象名)结束两种区别:setTimeout();定时执行,执行一次。clearTimeout(定时器对象名)结束;setInterval();定时执行,一直执行。clearInterval(定时器对象名)结束
- innerHTML和outerHTML的区别是什么?
innerHTML取页面元素标签内部的内容,outerHTML取包含元素标签的内容,如test,innerHTML取到test,outerHTML取到
test. - javascript如何做到页面局部刷新?
使用AJAX。原理:获取一个请求对象,向指定url发送请求,当请求完成时(状态4),获取到请求返回内容,并将内容填充到页面局部。
- 请列举数组和字符串的的可用方法?
数组常见方法1.push(参数1): 向数组尾部添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。var arr=[0,1,2,3,4];console.log(arr);//只要后面向数组添加了元素,打印出来的都是添加元素后的数组[ 1, 2, 3 ,4],var len =arr.push(5);//向数组尾部添加一个元素5,并返回新添加的数组的长度lengthconsole.log(len)//打印出来的是长度6console.log(arr)//打印出来的数组是添加元素之后的数组[ 1, 2, 3 ,4], 2.pop(): 删除数组的最后一个元素,并返回该元素。该方法会改变原数组。var arr=[1,2,3];console.log(arr);//打印出来的是删除元素后的数组[1,2]var b=arr.pop();//返回的是删除后的元素console.log(b);//打印出来的是最后一个元素3console.log(arr);//打印出来的是删除元素后的数组 3.unshift():在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。var arr = ['a', 'b', 'c'];var len=arr.unshift('x'); // 4console.log(arr); // ['x', 'a', 'b', 'c']4.shift():删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组。var arr = ['a', 'b', 'c'];var b=arr.shift() // 'a'console.log(arr) // ['b', 'c'] shift()方法还可以遍历并清空一个数组。 var list = [1, 2, 3, 4, 5, 6]; var item; while (item = list.shift()) { console.log(item);//遍历数组,循环的输出1,2,3,4,5,6.遍历完之后清空数组 }console.log(list); // 数组为空[] 5.valueOf():返回数组的本身。var arr = [1, 2, 3];var aarr=arr.valueOf();console.log(aarr); // [1, 2, 3] 6.indexOf():返回指定元素在数组中出现的位置,如果没有出现则返回-1。 var arr = ['a', 'b', 'c']; var n=arr.indexOf('c') // 2console.log(n);//打印出来的是2 var m=arr.indexOf('y'); // -1console.log(m);indexOf方法还可以接受第二个参数,表示搜索的开始位置。var nm=arr.indexOf('a', 1) //nm的值为 -1 7.toString():返回数组的以逗号分割的字符串形式。var arr = [1, 2, 3];var str=arr.toString() // "1,2,3"console.log(str);var arr = [1, 2, 3, [4, 5, 6]];var str1=arr.toString() ; // "1,2,3,4,5,6"console.log(str1); 8.join():以参数作为分隔符,将所有数组成员组成一个字符串返回。如果不提供参数,默认用逗号分隔 var arr = [1, 2, 3, 4];var str=arr.join()console.log(str);// "1,2,3,4"var str1=arr.join(' ')console.log(str1);// “1 2 3 4” var str2=arr.join(' | ')console.log(str2) // "1 | 2 | 3 | 4"9.concat():用于多个数组的合并。它将新数组的成员,添加到原数组的尾部,然后返回一个合并后的新数组,原数组不变。1 var arr = [1,2,3];2 var arr1 = arr.concat([4,5,6]);3 console.log(arr1); //[1,2,3,4,5,6]10.reverse():用于颠倒数组中元素的顺序,返回改变后的数组。注意,该方法将改变原数组。1 var arr = ['a', 'b', 'c'];var arr1=arr.reverse() // ["c", "b", "a"]console.log(arr1) // ["c", "b", "a"]console.log(arr) // 也是["c", "b", "a"] 11.slice():用于截取原数组的一部分,返回一个截取的新数组,原数组不变。slice(start,end)它的第一个参数为起始位置(从0开始),第二个参数为终止位置(但该位置的元素本身不包括在内)。如果省略第二个参数,则一直返回到原数组的最后一个成员。var arr = ['a', 'b', 'c'];arr.slice(0) // ["a", "b", "c"]arr.slice(1) // ["b", "c"]arr.slice(1, 2) // ["b"]arr.slice(2, 6) // ["c"]arr.slice() // ["a", "b", "c"] 无参数返回原数组arr.slice(-2) // ["b", "c"] 参数是负数,则表示取倒数的后两位arr.slice(-3) //[“a”,”b”,”c”] 表示 取倒数的后三位arr.slice(-2, -1) // ["b"] 表示取倒数的第二位,-1不包含在范围内arr.slice(-3,-2)//表示取倒数的第三位arr.slice(-3,-1)//表示取倒数的第二位和第三位12.splice():删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。splice(start,delNum,addElement1,addElement2,...)第一个参数是删除的起始位置,第二个参数是被删除的元素个数。如果后面还有更多的参数,则表示这些就是要被插入数组的新元素。var arr = ['a', 'b', 'c', 'd', 'e', 'f'];arr.splice(4, 2) // ["e", "f"] 从原数组4号位置,删除了两个数组成员console.log(arr) // ["a", "b", "c", "d"] var arr = ['a', 'b', 'c', 'd', 'e', 'f'];arr.splice(4, 2, 1, 2) // ["e", "f"] 原数组4号位置,删除了两个数组成员,又插入了两个新成员 console.log(arr) // ["a", "b", "c", "d", 1, 2] var arr = ['a', 'b', 'c', 'd', 'e', 'f']; arr.splice(-4, 2) // ["c", "d"] 起始位置如果是负数,就表示从倒数位置开始删除,从倒数第四个位置开始删除,并删除两个 var arr = [1, 1, 1];arr.splice(1, 0, 2) // [] 如果只插入元素,第二个参数可以设为0conlose.log(arr) // [1, 2, 1, 1] var arr = [1, 2, 3, 4];arr.splice(2) // [3, 4] 如果只有第一个参数,等同于将原数组在指定的位置开始删除,直到数组最后console.log(arr) // [1, 2]13.sort():对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。 1. ['d', 'c', 'b', 'a'].sort() // ['a', 'b', 'c', 'd'] 2.[4, 3, 2, 1].sort() // [1, 2, 3, 4] 3.[11, 101].sort() // [101, 11] 4. [10111, 1101, 111].sort() // [10111, 1101, 111]上面代码的最后两个例子,需要特殊注意。sort方法不是按照大小排序,而是按照对应字符串的字典顺序排序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以101排在11的前面。如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身又接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下,都是第一个元素排在第二个元素前面。var arr = [10111, 1101, 111];arr.sort(function (a, b) { return a - b;})// [111, 1101, 10111]var arr1 = [ { name: "张三", age: 30 }, { name: "李四", age: 24 }, { name: "王五", age: 28 } ]arr1.sort(function (o1, o2) { return o1.age - o2.age; }) // [ // { name: "李四", age: 24 },// { name: "王五", age: 28 },// { name: "张三", age: 30 } // ]10.map():参数是一个函数,对数组的所有成员依次调用一个函数,根据函数结果返回一个新数组。原数组不变。返回的是对原数组中的成员进行调用函数后的新数组。 var numbers = [1, 2, 3];var arr1=numbers.map(function (n) { return n + 1; });// arr1 = [2, 3, 4] //numbers = [1, 2, 3]上面代码中,numbers数组的所有成员都加上1,组成一个新数组返回,原数组没有变化。11.filter():参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。该方法不会改变原数组。var arr = [1, 2, 3, 4, 5]arr.filter(function (elem) { return (elem > 3);})// [4, 5],返回的是原数组中符合条件的成员 JS字符串常见用法字符串字符串就是一个或多个排列在一起的字符,放在单引号或双引号之中。'abc'"abc"length属性js里的字符串类似于数组,都是一个一个字符拼凑在一起组成的,因此可以用length属性取得字符串的长度var str = "hello"str.length; // 5字符串常用的一些方法1. charAt()str.charAt(n)=> 返回字符串的第 n 个字符,如果不在 0~str.length-1之间,则返回一个空字符串。var str = "javascript";str.charAt(2); //'v'str.charAt(12); //'' 字符串的操作在js中非常频繁,也非常重要。以往看完书之后都能记得非常清楚,但稍微隔一段时间不用,便会忘得差不多,记性不好是硬伤啊。。。今天就对字符串的一些常用操作做个整理,一者加深印象,二者方便今后温习查阅。String对象属性(1) length属性length算是字符串中非常常用的一个属性了,它的功能是获取字符串的长度。当然需要注意的是js中的中文每个汉字也只代表一个字符,这里可能跟其他语言有些不一样var str = 'abc';console.log(str.length);(2) prototype属性prototype在面向对象编程中会经常用到,用来给对象添加属性或方法,并且添加的方法或属性在所有的实例上共享。因此也常用来扩展js内置对象,如下面的代码给字符串添加了一个去除两边空格的方法:String.prototype.trim = function(){ return this.replace(/^\s*|\s*$/g, '');}String对象方法1.获取类方法(1) charAt()stringObject.charAt(index)charAt()方法可用来获取指定位置的字符串,index为字符串索引值,从0开始到string.leng – 1,若不在这个范围将返回一个空字符串。如var str = 'abcde';console.log(str.charAt(2)); //返回cconsole.log(str.charAt(8)); //返回空字符串(2) charCodeAt()stringObject.charCodeAt(index)charCodeAt()方法可返回指定位置的字符的Unicode编码。charCodeAt()方法与charAt()方法类似,都需要传入一个索引值作为参数,区别是前者返回指定位置的字符的编码,而后者返回的是字符子串。var str = 'abcde';console.log(str.charCodeAt(0)); //返回97(3) fromCharCode()String.fromCharCode(numX,numX,…,numX)fromCharCode()可接受一个或多个Unicode值,然后返回一个字符串。另外该方法是String 的静态方法,字符串中的每个字符都由单独的数字Unicode编码指定。String.fromCharCode(97, 98, 99, 100, 101) //返回abcde2.查找类方法(1) indexOf()stringObject.indexOf(searchvalue,fromindex)indexOf()用来检索指定的字符串值在字符串中首次出现的位置。它可以接收两个参数,searchvalue表示要查找的子字符串,fromindex表示查找的开始位置,省略的话则从开始位置进行检索var str = 'abcdeabcde';console.log(str.indexOf('a')); // 返回0console.log(str.indexOf('a', 3)); // 返回5console.log(str.indexOf('bc')); // 返回1(2) lastIndexOf()方法stringObject.lastIndexOf(searchvalue,fromindex)lastIndexOf()语法与indexOf()类似,它返回的是一个指定的子字符串值最后出现的位置,其检索顺序是从后向前。var str = 'abcdeabcde';console.log(str.lastIndexOf('a')); // 返回5console.log(str.lastIndexOf('a', 3)); // 返回0 从第索引3的位置往前检索console.log(str.lastIndexOf('bc')); // 返回6(3) search()方法stringObject.search(substr)stringObject.search(regexp)search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。它会返回第一子字符个匹配的串的起始位置,如果没有匹配的,则返回-1。var str = 'abcDEF';console.log(str.search('c')); //返回2console.log(str.search('d')); //返回-1console.log(str.search(/d/i)); //返回3(4) match()方法stringObject.match(substr)stringObject.match(regexp)match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。如果参数中传入的是子字符串或是没有进行全局匹配的正则表达式,那么match()方法会从开始位置执行一次匹配,如果没有匹配到结果,则返回null。否则则会返回一个数组,该数组的第0个元素存放的是匹配文本,除此之外,返回的数组还含有两个对象属性index和input,分别表示匹配文本的起始字符索引和stringObject 的引用(即原字符串)。var str = '1a2b3c4d5e';console.log(str.match('h')); //返回nullconsole.log(str.match('b')); //返回["b", index: 3, input: "1a2b3c4d5e"]console.log(str.match(/b/)); //返回["b", index: 3, input: "1a2b3c4d5e"]如果参数传入的是具有全局匹配的正则表达式,那么match()从开始位置进行多次匹配,直到最后。如果没有匹配到结果,则返回null。否则则会返回一个数组,数组中存放所有符合要求的子字符串,并且没有index和input属性。var str = '1a2b3c4d5e';console.log(str.match(/h/g)); //返回nullconsole.log(str.match(/\d/g)); //返回["1", "2", "3", "4", "5"]3.截取类方法(1) substring()stringObject.substring(start,end)substring()是最常用到的字符串截取方法,它可以接收两个参数(参数不能为负值),分别是要截取的开始位置和结束位置,它将返回一个新的字符串,其内容是从start处到end-1处的所有字符。若结束参数(end)省略,则表示从start位置一直截取到最后。var str = 'abcdefg';console.log(str.substring(1, 4)); //返回bcdconsole.log(str.substring(1)); //返回bcdefgconsole.log(str.substring(-1)); //返回abcdefg,传入负值时会视为0(2) slice()stringObject.slice(start,end)slice()方法与substring()方法非常类似,它传入的两个参数也分别对应着开始位置和结束位置。而区别在于,slice()中的参数可以为负值,如果参数是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符。var str = 'abcdefg';console.log(str.slice(1, 4)); //返回bcdconsole.log(str.slice(-3, -1)); //返回efconsole.log(str.slice(1, -1)); //返回bcdefconsole.log(str.slice(-1, -3)); //返回空字符串,若传入的参数有问题,则返回空(3) substr()stringObject.substr(start,length)substr()方法可在字符串中抽取从start下标开始的指定数目的字符。其返回值为一个字符串,包含从 stringObject的start(包括start所指的字符)处开始的length个字符。如果没有指定 length,那么返回的字符串包含从start到stringObject的结尾的字符。另外如果start为负数,则表示从字符串尾部开始算起。var str = 'abcdefg';console.log(str.substr(1, 3)) //返回bcdconsole.log(str.substr(2)) //返回cdefgconsole.log(str.substr(-2, 4)) //返回fg,目标长度较大的话,以实际截取的长度为准4.其他方法(1) replace()方法stringObject.replace(regexp/substr,replacement)replace()方法用来进行字符串替换操作,它可以接收两个参数,前者为被替换的子字符串(可以是正则),后者为用来替换的文本。如果第一个参数传入的是子字符串或是没有进行全局匹配的正则表达式,那么replace()方法将只进行一次替换(即替换最前面的),返回经过一次替换后的结果字符串。var str = 'abcdeabcde';console.log(str.replace('a', 'A'));console.log(str.replace(/a/, 'A'));如果第一个参数传入的全局匹配的正则表达式,那么replace()将会对符合条件的子字符串进行多次替换,最后返回经过多次替换的结果字符串。var str = 'abcdeabcdeABCDE';console.log(str.replace(/a/g, 'A')); //返回AbcdeAbcdeABCDEconsole.log(str.replace(/a/gi, '$')); //返回$bcde$bcde$BCDE(2) split()方法stringObject.split(separator,howmany)split()方法用于把一个字符串分割成字符串数组。第一个参数separator表示分割位置(参考符),第二个参数howmany表示返回数组的允许最大长度(一般情况下不设置)。var str = 'a|b|c|d|e';console.log((str.split(" ") )//空格用来分割每个英语单词console.log(str.split('|')); //返回["a", "b", "c", "d", "e"]console.log(str.split('|', 3)); //返回["a", "b", "c"]console.log(str.split('')); //返回["a", "|", "b", "|", "c", "|", "d", "|", "e"]也可以用正则来进行分割var str = 'a1b2c3d4e';console.log(str.split(/\d/)); //返回["a", "b", "c", "d", "e"](3) toLowerCase()和toUpperCase()stringObject.toLowerCase()stringObject.toUpperCase()toLowerCase()方法可以把字符串中的大写字母转换为小写,toUpperCase()方法可以把字符串中的小写字母转换为大写。var str = 'JavaScript';console.log(str.toLowerCase()); //返回javascriptconsole.log(str.toUpperCase()); //返回JAVASCRIPT
- 请实现,鼠标点击页面中的任何标签,alert该标签的名称?
var el = document.getElementsByTagName('body');el[0].οnclick=function(event){evt=event||window.event;var selected=evt.target||evt.srcElement;alert(selected.tagName);}
- 完成一个正则表达式,验证输入是否为合法的邮箱号?
\d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{ 3},^$分别是什么?\d:匹配数字\w:匹配字母或数字或下划线或汉字\s:匹配任意的空白符[a-zA-z0-9]:匹配任意字母和数字\b:匹配单词的开始或结束. :匹配除换行符以外的任意字符*:重复零次或更多次+:重复一次或更多次? :重复零次或一次x{ 3}:重复三次x^$:匹配行的开始处和结束处贪婪模式和非贪婪模式指什么?贪婪模式:当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配*懒惰模式**:匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复代码写一个函数trim(str),去除字符串两边的空白字符代码: function trim(str){ newstr = str.replace(/^\s*|\s*$/,''); return newstr } var a = ' asdas dasdasd ' console.log(trim(a)) 使用实现 addClass(el, cls)、hasClass(el, cls)、removeClass(el,cls),使用正则//提示: el为dom元素,cls为操作的class, el.className获取el元素的class代码: //提示: el为dom元素,cls为操作的class, el.className获取el元素的class function addClass(el, cls) { if (!hasClass(el, cls)) { el.className += " " + cls; } } function hasClass(el, cls) { var reg = new RegExp('\\b' + cls + '\\b', 'g'); return reg.test(el.className); } function removeClass(el, cls) { var reg = new RegExp('\\b' + cls + '\\b', 'g'), tmp = node.className.replace(reg, '').replace(/\s{ 2,}/g, ' '); //把两个以上的空格替换为一个空格 el.className = trim(tmp); } 写一个函数isEmail(str),判断用户输入的是不是邮箱代码: function isEmail(str){ reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){ 1,63}[a-z0-9]+$/g return reg.test(str) } console.log(isEmail('a'))//false console.log(isEmail('123@qq.com'))//true console.log(isEmail('zzzzzzzdadasdqweqwedq@163.com'))//true console.log(isEmail('w-eqwdasd@qq.com'))//true 写一个函数isPhoneNum(str),判断用户输入的是不是手机号代码: function isPhone(str){ reg = /^1[3|5|7|8]\d{ 9}$/g return reg.test(str) } console.log(isPhone('110'))//false console.log(isPhone('13893000000'))//true console.log(isPhone('1881333900'))//false console.log(isPhone('12345678901'))//false console.log(isPhone('17045678901'))//true 写一个函数isValidUsername(str),判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线)代码: function isValidUsername(str){ reg = /^[0-9a-zA-Z|_]{ 6,20}$/g return reg.test(str) } console.log(isValidUsername('111111!'))//false console.log(isValidUsername('zxw1111_'))//true console.log(isValidUsername('zxw_2131242153243241'))//true console.log(isValidUsername('zxw$$aweeqweqw'))//false console.log(isValidUsername('zxczxwZZX'))//true 写一个函数isValidPassword(str), 判断用户输入的是不是合法密码(长度6-20个字符,包括大写字母、小写字母、数字、下划线至少两种)代码: function isValidPassword(str){ if(str.length<6||str.length>20){ return false } if(/[^a-zA-Z0-9_]/.test(str)){ return false } if(/(^[a-z]+$|^[A-Z]+$|^\d+$|^_+$)/.test(str)){ return false } return true } console.log(isValidPassword('zxw1992513')) 写一个正则表达式,得到如下字符串里所有的颜色(#121212) var re = /*正则...*/ var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 " alert( subj.match(re) ) // #121212,#AA00ef代码: var re = /#[0-9a-fA-F]{ 6}/g/*正则...*/ var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 " alert( subj.match(re) ) // #121212,#AA00ef下面代码输出什么? 为什么? 改写代码,让其输出hunger, world. var str = 'hello "hunger" , hello "world"'; var pat = /".*"/g; str.match(pat);因为是贪婪模式,会把最外""中内容输出,即输出"hunger" , hello "world"代码: //方法一 var str = 'hello "hunger" , hello "world"'; var pat = /"\w*"/g; str.match(pat); console.log(str.match(pat)) //方法二 var str = 'hello "hunger" , hello "world"'; var pat = /".*?"/g; str.match(pat); console.log(str.match(pat))补全如下正则表达式,输出字符串中的注释内容. (可尝试使用贪婪模式和非贪婪模式两种方法) str = '.. .. .. ' re = /.. your regexp ../ str.match(re) // ' ', ' '代码: //贪婪模式 str = '.. .. .. ' re = / /g str.match(re) // ' ', ' ' console.log(str.match(re)) //非贪婪模式 str = '.. .. .. ' re = / /g str.match(re) // ' ', ' ' console.log(str.match(re))补全如下正则表达式 var re = /* your regexp */ var str = '<> ' str.match(re) // '', '', ''代码: var re = /<{FNXX==XXFN}+>/g var str = '<> ' str.match(re) // '', '', '' console.log(str.match(re))
- 实现垂直居中的css?
利用css实现垂直居中的方法1.如果是单行文本。(子元素是块级元素,则设置子元素的line-height等于父元素的高,可使子元素垂直居中与父元素)
Document 这是一段要垂直水平居中的文字!
Document 这是一段要垂直水平居中的文字!这是一段要垂直水平居中的文字!
Document 居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧中吧~Document Document Document Document 居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~居中吧~6.当子元素为(行内,块级)元素时,子元素使用绝对定位和0{ height:700px;//当子元素为块级元素时,还可以设置高度 width:50%; height:50%; background: #fff; overflow: auto; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; }看代码:Document tytyty注意:如果是行内元素为img,省略掉width:50%;height:50%;也可Document - 以下代码的运行结果是什么,如果希望看到控制台每隔一秒输出一个数字,连续输出1-9,应该如何修改代码?
for(var i=0;i<10;i++){ setTimeout(function(){ console.log(i); },1000); } 答案是:打印了10次10,setTimeOut是异步进行的。
for (var i = 0; i < 5; i++) {(function (j) { // j = isetTimeout(function () {console.log(new Date, j);}, 1000);})(i);}以上使用自执行方法解决,只有一个作用:创建一个独立的作用域。打印结果:Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 0
VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 1VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 2VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 3VM59:4 Wed Mar 28 2018 11:35:14 GMT+0800 (中国标准时间) 4以上在同一时间分别打印0,1,2,3,4
for(var i=0;i<=3;i++){
setTimeout(function() {
console.log(i)
}, 10);
}
答案:打印4次4
这道题涉及了异步、作用域、闭包?
settimeout是异步执行,10ms后往任务队列里面添加一个任务,只有主线上的全部执行完,才会执行任务队列里的任务,当主线执行完成后,i是4,所以此时再去执行任务队列里的任务时,i全部是4了。对于打印4次是:
每一次for循环的时候,settimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行,for循环了4次,就放了4次,当主线程执行完成后,才进入任务队列里面执行。(注意:for循环从开始到结束的过程,需要维持几微秒或几毫秒。)当我把var 变成let 时for(let i=0;i<=3;i++){setTimeout(function(){console.log(i) },10);}打印出的是:0,1,2,3当解决变量作用域,因为for循环头部的let不仅将i绑定到for循环快中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。
查了一下百度的一个答案:
setTimeout是一次执行函数,这里是10ms后执行,仅仅执行一次;for(var i=0;i<=3;i++),i的每次取值都是执行setTimeout这个函数,并没有执行setTimeout里面的function(即闭包函数),setTimeout里面的function是有setTimeout的定时触动的,也就是10ms后执行,也就是说i从0~3时,一共执行了4次的setTimeout()函数,此时的i的值是4,由于for语句的执行速度远小于1秒,所以,1秒后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是4了,所以相继打印4次i.
JavaScript中var、let、const区别?
简单来说是: let是修复了var的作用域的一些bug,变的更加好用。let是更好的var。var的作用域是函数作用域由var定义的变量,它作用域在一个函数体内,而不是我们其他语言理解的大括号{ }内。而let是块级别(大括号括起来的内容)
const声明的变量只可以在声明时赋值,不可随意修改,这是最大的特点。
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象;
使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升;
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); //6
console.log(a[6]); // function(){console.log(i)}
既然循环结束后,数组a的每一项都是function(){console.log(i)},那么a[6]()输出是6是怎么实现的?难道let保存了10个状态?
这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
var a = [];for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};}
a[6](); // 10
上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。
也就是说,循环结束后,数组a的每一项都是function(){console.log(i)}。在执行a[6]函数前,此时i的值已经是10了。
- 编写一个javascript函数,消除下面数组里的重复元素,var arr = [1,5,8,4,7,4,9,6,8,7];
- 输出结果
var name = "The window"; var object = { name: "My Object", getNameFunc: function () { return function () { return this.name;//闭包没有访问外层函数的变量,闭包里的this没有具体指向。 } }} console.log(object.getNameFunc()());
) 打印的是:"The window";
- 输出结果
function Obj(){}var a = new Obj(),b = new Obj();Obj.prototype.age = 20;Obj.prototype.name = { "firstName":"Jhon"}b.age = 10;b.name.firstName = "Bob";alert(a.age);//20alert(a.name.firstName);//Bob
function Obj(){}
var a = new Obj(),b = new Obj();Obj.prototype.age = 20;Obj.prototype.name = { "firstName":"Jhon"}b.age = 10;b.name = {firstName:"yys"};alert(a.age);//20alert(a.name.firstName);//Jhonalert(b.name.firstName);//yys
从原理跟你说起。首先Js有一隐性规则,js中任何变量(属性)都是基于Object这个构造函数创建的,所以Js没有严格的类型区分,因为所有的类型都可以是Object。又,在js中Object是可以用点运算符(.)来为对象新增属性或方法的,所以你的b也是一个Object,自然也就能新增属性,然而这个新增的属性是一个自身属性,没有任何特殊。(语法糖?)
b.name.firstName = "Bob";b.name.firstName 是对原型上属性的引用,那么你对它操作的时候,实际上就是对原型上操作。但是b.name = {firstName:"yys"};//这句话是为对象添加一个自身的属性并赋值。这就不同了,相当于给person1这个对象实例添加了一个属性,不是给原型添加。关键在于=。
由此我们也可以看出另外一层意思:如果对象实例中包含和原型对象中同名的属性或方法,则对象实例中的该同名属性或方法会屏蔽原型对象中的同名属性或方法。原因就是“首先在该对象中查找该属性,若找到,返回该属性值;”
function Person () {}
Person.prototype = {
constructor: Person,
name: 'xu',
age: ['1', '2'],
sex: '男',
showAge: function () {
console.log(this.age);
}
}
var person1 = new Person();
var person2 = new Person();
person1.age.push('3');
console.log(person1.age, person2.age); // ['1', '2', '3'] , ['1', '2', '3']
person1.age = ['1'];
console.log(person1.age, person2.age); // ['1'] , ['1', '2', '3']
从原理跟你说起。首先Js有一隐性规则,js中任何变量(属性)都是基于Object这个构造函数创建的,所以Js没有严格的类型区分,因为所有的类型都可以是Object。又,在js中Object是可以用点运算符(.)来为对象新增属性或方法的,所以你的persion1也是一个Object,自然也就能新增属性,然而这个新增的属性是一个自身属性,没有任何特殊。(语法糖?)
person1.age.push('3');
是对属性的引用,那么你对它操作的时候,实际上就是对原型上操作。但是
person1.age = ['1'];//这句话是为对象添加一个自身的属性并赋值。
这就不同了,相当于给person1这个对象实例添加了一个属性,不是给原型添加。关键在于=。
age在prototype上定义所以是类属性 所以可以正常访问它 但是后面那个赋值实际上是设置了一个实例属性 这是不能共享的 通常对类的改写应该写成修改prototype属性 就是说你第一个也应该写Person.prototype.age.push()。
一开始, person1.age与person2.age指向同一个引用,即Person.prototype.age所指向的那个对象。person1.age = ['1'];
这一步后,person1.age指向一个新建的数组对象,然而person2.age不变依然指向Person.prototype.age指代的对象。之后对person1的操作都是对['1']数组对象的操作,而不是对其原型链上对象的操作,肯定就不会改变了,因为都不是一个对象。
因为 Array 是引用类型,多个相同的引用副本指向的是同一个 Array 对象。既然对同一个对象进行 push,其他引用该对象的自然也就变了。而重新赋值后相当于新建了一个与原型不同的 Array 对象,其他对象并没有此 Array 的引用,所以对它的修改不会影响到原型中的 Array 对象。
当我们需要读取对象的某个属性时,都会执行一次搜索。首先在该对象中查找该属性,若找到,返回该属性值;否则,到[[prototype]]指向的原型对象中继续查找。
由此我们也可以看出另外一层意思:如果对象实例中包含和原型对象中同名的属性或方法,则对象实例中的该同名属性或方法会屏蔽原型对象中的同名属性或方法。原因就是“首先在该对象中查找该属性,若找到,返回该属性值;”
1.
function Person () {}
Person.prototype = {
constructor: Person,
name: 'xu',
age: ['1', '2'],
sex: '男',
showAge: function () {
console.log(this.age);
}
}
var person1 = new Person();
var person2 = new Person();
person1.age = ['1'];
console.log(person1.age, person2.age); // [ "1", "3" ] ,[ "1", "2" ]
person1.age.push('3');
console.log(person1.age, person2.age); // [ "1", "3" ] ,[ "1", "2" ]
2.
function Person () {}
Person.prototype = {
constructor: Person,
name: 'xu',
age: ['1', '2'],
sex: '男',
showAge: function () {
console.log(this.age);
}
}
var person1 = new Person();
var person2 = new Person();
person1.age = ['1'];
console.log(person1.age, person2.age); // [ "1" ] ,[ "1", "2", "3" ]
person2.age.push('3');
console.log(person1.age, person2.age); //[ "1" ] ,[ "1", "2", "3" ]