目录
5、兼容、优化、项目中的难点如何解决 是面试官最喜欢问的问题
1、ECMAScript (简称ES),js语言核心部分,描述了该语言的语法和基本对象;
2、文档对象模型(DOM),网页文档操作标准;
3、浏览器对象模型(BOM),客户端和浏览器窗口操作基础。
- var a=100
- a=a+21
- var b=a%19
- var re=typeof(b)
- // re变量的数据类型是什么
- console.log(typeof(re))
答案:string
- var obj={age:20}
- var a=100
- var c=(-a+++obj.age++)
- console.log(c)
答案: -80
-
- var a=(b=0) && (c=30)
- console.log(a)
- console.log(b)
- console.log(c)
0 0 报错
此代码不是由i++决定的,逗号操作符,最后一个表达式作为结果,所以i<5才是判定条件
flase根本不会执行,因为从B语句开始
- var i=0;
- for(;i++,i<5;) {
- console.log(i)
- } //1 2 3 4
-
-
- var i=0;
- for(false;i++,i<5;) {
- console.log(i)
- } //1 2 3 4
-
- for(var i=0,j=6;i<4,j>0;i++,j--) {
- console.log(i)
- } //06 15 24 33 42 51
- //所以打印 0 1 2 3 4 5
-
- var arr=[]
- for(var i=0;i<4;i++) {
- arr[i]=function(){console.log(i)}
- }
- arr[0]() //4
- arr[2]() //4
-
基本数据取一个成员是可以的,但是是undefined
- function a(xx) {
- this.x=xx
- return this
- }
- var x=a(5) //a=6
- var y=a(6) //y=window
- console.log(x.x) //undefined 6.x==>基本数据取一个成员是可以的,但是是undefined
- console.log(y.x) //6 window.x=6
- function sum() {
- if (arguments.length == 2) {
- return arguments[0] + arguments[1];
- } else if (arguments.length == 1) {
- var first = arguments[0];
- return function(second) {
- return first + second;
- };
- }
- }
- console.log(sum(2,3));
- console.log(sum(2)(3));
5 5
- var fn = 90;
- var o = {
- fn: function() {
- console.log(fn); //90 上一排的fn只有对象o才可以使用
- }
- }
- console.log(o.fn());
- var fn = 90;
- var o = {
- fn: function fm() {
- console.log(fm); //fm函数,这样写就可以访问
- }
- }
- console.log(o.fn());
- var User = {
- count: 1,
- getCount: function() {
- return this.count
- }
- }
- var fn = User.getCount
- console.log(fn());
undefined
- var buttons = [{name:'b1'},{name:'b2'},{name:'b3'}];
- function bind(){
- for (var i = 0; i < buttons.length; i++) {
- buttons[i].onclick = function() {
- console.log(i);
- }
- }
- };
- bind();
- buttons[0].onclick();
- buttons[1].onclick();
- buttons[2].onclick();
答案: 3 3 3
console.log(i);是在最后调用的时候才取i,foe循环已经完了,就是3了
如果想最后的值不一样,有两种方法:
1、将var改成let
2、使用闭包
但是这样写有两个问题:1内存泄露 2程序不太好阅读
-
- var buttons = [{name:'b1'},{name:'b2'},{name:'b3'}];
- function bind(){
- for (var i = 0; i < buttons.length; i++) {
- (function(index){
- buttons[i].onclick = function() {
- console.log(index);
- }
- })(i)
- }
- };
- bind();
- buttons[0].onclick(); //0
- buttons[1].onclick(); //1
- buttons[2].onclick(); //2
- var a=b=3
- console.log("a defined? " + (typeof a !== 'undefined'));//false
- console.log("b defined? " + (typeof b !== 'undefined'));//true
- console.log(b);//3
- console.log(typeof a);//'undef'
-
- var re1=typeof(a)
- var re2=typeof(b)
- // 变量a的值
- console.log(a) //没有值,会报错 因为它是局部变量
- //变量b的值 //3
- //变量re1的值 //"undf"
- //变量re1的数据类型 //string
- //变量re2的值 //"number"
- //变量re2的数据类型 //string
- console.log(typeof re2)
- //变量a的数据类型 //unf
- //变量b的数据类型 //number
var a=b=3 ==> b=3;var a=3
- var fn1 = 'ivan';
- var name = 'good';
- var fn1 = function(y) {
- y();
- }
- function fn1(x) {
- x(name);
- }
- function fn2(x) {
- console.log(x);
- console.log(name);
- var name = 'hello';
- console.log(name);
- }
- fn1(fn2);
答案:undefined undefined hello
- var num = 5;
- function func1() {
- var num = 3;
- var age = 4; //6
- function func2() {
- console.log(num); //und
- var num = 'ivan';
- function func3() {
- age = 6;
- }
- func3();
- console.log(num); //ivan
- console.log(age); //6
- }
- func2();
- }
- func1();
- function changeObjectProperty(o) {
- o.siteUrl = "http://www.csser.com/";
- o = new Object();
- o.siteUrl = "http://www.popcg.com/";
- return o
- }
- var CSSer = new Object();
- var re=changeObjectProperty(CSSer);
- console.log(CSSer.siteUrl);
- console.log(re.siteUrl)
- // re=null; //因为return了o,并且还使用了,所以要释放
答案:
http://www.csser.com/
index.html:169 http://www.popcg.com/
- var x = 8;
- var objA = {
- x: 'good',
- y: 32//5
- }
- function add(x, y) {
- console.log(x.y + y);
- }
- function fn(x, y) {
- x.y = 5;
- y(x, 3);
- }
- fn(objA, add);
- console.log(objA);
- var obj1 = new Object();
- obj1.name = 'zjzhome';
- var obj2 = obj1;
- console.log(obj2.name);//'zjzhome'
- obj1.name = 'zjz';
- console.log(obj2.name);//'zjz'
- var a = '' + 3;
- var b = 4;
- console.log(typeof a); //"string"
- console.log(a + b); //"34"
- console.log(a - b); //-1 数值类型的字符串可以跟数字减法运算
- console.log({} - b) //NaN
- //number: NAN 200 100 10.2 Infinity
-
- var foo = "11" + 2 + "1";
- console.log(foo); //"1121"
- console.log(typeof foo); //"string"
-
- var foo1 = "11" + 2 + 1;
- console.log(foo1) //1121 加号是从左到右
-
- var foo2 = "11" + 2 * 2;
- console.log(foo2) //114 //乘号优先级高
- var name = 'laruence';
- function echo() {
- console.log(name);
- }
- function env() {
- var name = 'eve';
- echo();//'laruence';
- }
- env();
- a = new Array(2, 3, 4, 5, 6);
- sum = 0;
- for (i = 1; i < a.length; i++)
- sum += a[i];
- console.log(sum);//18
可以不用写var i
- var f = true;
- if (f === true) {
- var a = 10;
- }
- function fn() {
- var b = 20;
- c = 30;
- }
- fn();
- console.log(a); //10
- console.log(b); //代码报错,以至于后面的代码也不会运行了
- console.log(c); //30
- 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();
- getName();
- Foo().getName();
- getName();
- new Foo.getName();
- new Foo().getName();
- new new Foo().getName();
函数点语法,是给函数添加一个方法,不会改变函数里面得代码
new Foo()==> this不是window,是创建的那个对象,就是构造函数的那三步
- /*
- var getName
- function Foo() {
- getName = function() {
- console.log(1);
- }
- return this;
- }
- Foo.getName = function() {console.log(2)}
- Foo.prototype.getName = function() {console.log(3)}
- getName = function() {console.log(4)}
- Foo.getName(); //2
- getName(); //4
- getName = function() {
- console.log(1);
- }
- Foo().getName(); //1
- getName(); //1
- new Foo.getName(); //2
- new Foo().getName(); //3
- //(new Foo()).getName()
- getName = function() {
- console.log(1);
- }
- //new Foo()==> {__prroto__:Foo.prototype:Foo.prototype.getName = function() {console.log(3)}}
- //new Foo()==> this不是window,是创建的那个对象,就是构造函数的那三步
- new new Foo().getName(); //3
- //new ((new Foo()).getName)();
- getName = function() {
- console.log(1);
- }
- new Foo()==> {__prroto__:Foo.prototype:Foo.prototype.getName = function() {console.log(3)}}
- */
window.location.href //获取当前地址的网址
- window.location.href //获取当前地址的网址
- var url='http://www.baidu.com/?user=karen&page=10&count=100'
- function parseurl (str) {
- var arr=str.split("?")[1]
- var arr2=arr.split("&")
- var obj={}
- for(var i=0;i<arr2.length;i++) {
- var arr3=arr2[i].split("=")
- obj[arr3[0]]=arr3[1]
- }
- return obj
- }
- var re=parseurl(url)
- console.log(re)
- console.log(typeof''.prototype)
- console.log(typeof''.__proto__)
- console.log(typeof''.__proto__===typeof''.prototype)
1、'undefined'
2、'object' //new String() 是一个对象
3、false
- var re =['1','2','3'].map(parseInt)
- console.log(re)
结果:(3) [1, NaN, NaN]
解析:
map函数是将数组的每个元素传递给指定的函数处理,并返回处理后的数组,所以["1", "2", "3"].map(parseInt)就是将字符串1,2,3作为元素,0,1,2作为下标分别调用parseInt函数,即分别求出parseInt('1', 0),parseInt('2', 1),parseInt('3', 2)的结果
==>
// parseInt('1', 0) -> 1 radix 为 0,parseInt() 会根据十进制来解析,所以结果为 1;
// parseInt('2', 1) -> radix 为 1,超出区间范围,所以结果为 NaN;
// parseInt('3', 2) -> NaN radix 为 2,用2进制来解析,应以 0 和 1 开头,所以结果为 NaN。
因为parseInt接收两个参数,所以结果为 [1, NaN, NaN]
知识:
1、map方法会传递3个参数
arr.map(function(item, index, arr){ ..... });2、parseInt 有两个参数
第一个是string==>必须,要被解析的字符串
第二个是radix==>可选,表示要解析的数字的基数,该值介于2-36
(默认值: 0x开头解析为16进制,0开头,解析为8或者16进制,1-9的数字开头,解析为10进制)
如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
console.log(-1 >>> 32) //4294967295 2的32次方 -1
答案:选 D
29、不改变原来数组,拷贝出数组b,且满足b!=a
请问下面哪种方式可以在不改变原来数组的情况下,拷贝出数组b,且满足b!=a
例如数组a为[1,2,3]
A.let b=a.slice()
B.let b=a
C.let b=a.splice(0,0)
D.let b=a.concat()
解析:此题类似于深拷贝,深拷贝是不改变原来的,而且让新的与原来的不相等,里面所有层都不相等==》此题是只要第一层不相等就可以了
- var a=[1,2,3]
- let b=a.slice()
- console.log(a,b) //(3) [1, 2, 3] (3) [1, 2, 3]
-
- let c=a //是同一个数组
-
- var a=[1,2,3]
- let d=a.splice(0,0) //下标为0的位置,删除0个元素,不插入元素。返回删除的元素装在数组中
- console.log(a,d) //(3) [1, 2, 3] []
-
- var a=[1,2,3]
- let e=a.concat() //数组的拼接,将a中的拼接到b中,所以成立
- console.log(a,e) //(3) [1, 2, 3] (3) [1, 2, 3]
渐进增强:在网页开发中,渐进增强认为应该专注于内容本身,一开始针对低版本的浏览器构建页面,满足最基础功能后,再针对高级浏览器进行效果交互,追加各种功能以达到更好的用户体验;即以最低的要求实现最基本的功能,向上兼容
优雅降级:指一开始针对高版本/高级浏览器进行页面构建,先完善所有功能后,再针对各个不同的浏览器进行测试,修复,保证低版本浏览器也有进本功能;即以高要求,高版本浏览器为准,向下兼容
两者的区别:
a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给
b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。