个人js错题集(4)

1.Jq中找到指定div元素id为user错误的

$("#user")
B  $("#"+"user")
C  $("div[id=user]")
D  $("div[id==user]")
 
正确答案: D
解析:元素获取

find用法:

1.为什么要用find:

通常,选择一个元素很简单,$("#id")就可以搞定,

但是如果想选择某个id为x1的div下的某个id为x2的元素就很困难了,

可以通过用find来解决这个问题。

2.find怎么用:

①首先贴出api中find的构造方法

find(expr|obj|ele)   返回值:jQuery

find的参数可以为用于查找的表达式,一个用于匹配元素的jQuery对象,一个DOM元素

find的返回值是juqery类型

②举例说明

html代码如下:


<div id="test">
<div id="div1">第一行</div>

<div id="div2">
<p id="p1">第1行</p>
<p id="p2">第2行</p>
<p id="p3">第3行</p>
</div>

<div id="div3">第三行</div>
<div id="div4">第四行</div>
</div>
如果想让第2行这几个字的颜色改变,那么我们就可以用jquery的如下代码实现:
$("#test").find('div[id^="div2"]').find('p[id^="p2"]').css("color","red");

那么效果就会变为:

第一行
第1行

第2行

第3行

第三行
第四行

2.有代码 var obj1={    a:[1],    b:1 }; var obj2={    a:[2],    c:2 }; var obj = Object.assign(obj1,obj2); 运行之后obj的结果为
A  {a:[1],b:1}
B  {a:[1,2],b:1,c:2}
C  {a:[2],b:1,c:2}
D  {a:[2],c:2}
 
正确答案: C
解析:
Object.assign是ES6新添加的接口,主要的用途是用来合并多个JavaScript的对象。

var target  = {a : 1}; //目标对象

var source1 = {b : 2}; //源对象1

var source2 = {c : 3}; //源对象2

var source3 = {c : 4}; //源对象3,和source2中的对象有同名属性c

Object.assign(target,source1,source2,source3);

Object.assign()用法讲解
语法: Object.assign(target, …sources) target: 目标对象,sources: 源对象
用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);

console.log(target); // Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // Object { a: 1, b: 4, c: 5 }

用法示例:
1.复制一个对象
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

2.深拷贝问题
针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。
let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

obj1.a = 1;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

obj2.a = 2;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}

obj2.b.c = 3;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}

// 深拷贝
obj1 = { a: 0 , b: { c: 0}};
let obj3 = JSON.parse(JSON.stringify(obj1));
obj1.a = 4;
obj1.b.c = 4;
console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}

3.合并对象
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

4.合并具有相同属性的对象
const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };

const obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 },注意属性被后续参数中具有相同属性的其他对象覆盖

5.继承属性和不可枚举属性是补课拷贝的
const obj = Object.create({foo: 1}, { // foo 是个继承属性。
bar: {
value: 2 // bar 是个不可枚举属性。
},
baz: {
value: 3,
enumerable: true // baz 是个自身可枚举属性。
}
});

const copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }
6.原始类型会包装为对象
const v1 = "abc";
const v2 = true;
const v3 = 10;
const v4 = Symbol("foo")

const obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// 原始类型会被包装,null 和 undefined 会被忽略。
// 注意,只有字符串的包装对象才可能有自身可枚举属性。
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

7.拷贝Symbol类型的属性
const o1 = { a: 1 };
const o2 = { [Symbol('foo')]: 2 };

const obj = Object.assign({}, o1, o2);
console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]

8.异常会打断后续的拷贝
const target = Object.defineProperty({}, "foo", {
value: 1,
writable: false
}); // target 的 foo 属性是个只读属性。

Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});
// TypeError: "foo" is read-only
// 注意这个异常是在拷贝第二个源对象的第二个属性时发生的。

console.log(target.bar); // 2,说明第一个源对象拷贝成功了。
console.log(target.foo2); // 3,说明第二个源对象的第一个属性也拷贝成功了。
console.log(target.foo); // 1,只读属性不能被覆盖,所以第二个源对象的第二个属性拷贝失败了。
console.log(target.foo3); // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的。
console.log(target.baz); // undefined,第三个源对象更是不会被拷贝到的。

9.拷贝访问器
const obj = {
foo: 1,
get bar() {
return 2;
}
};

let copy = Object.assign({}, obj);
console.log(copy); // { foo: 1, bar: 2 } copy.bar的值来自obj.bar的getter函数的返回值

// 下面这个函数会拷贝所有自有属性的属性描述符
function completeAssign(target, ...sources) {
sources.forEach(source => {
let descriptors = Object.keys(source).reduce((descriptors, key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {});

// Object.assign 默认也会拷贝可枚举的Symbols
Object.getOwnPropertySymbols(source).forEach(sym => {
let descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(target, descriptors);
});
return target;
}

copy = completeAssign({}, obj);
console.log(copy);
// { foo:1, get bar() { return 2 } }

3.下列箭头函数书写正确的是

A  0--{}
B  a,b => {}
C  _ =>
D  caller
 
正确答案: C
解析:

箭头函数用 => 符号来定义。

箭头函数相当于匿名函数,所以采用函数表达式的写法。

左边是传入函数的参数,右边是函数中执行的语句。

相当于

上面是完整的写法,左边小括号,右边大括号,而下面的情况可以简写:

(1)当要执行的代码块只有一条return语句时,可省略大括号和return关键字:

(2)当传入的参数只有一个时,可以省略小括号:

相当于

(3)当不需要参数时,使用空的圆括号:

相当于

箭头函数在回调函数中是很简洁的,像这样:

在排序中:

需要注意的是, 箭头函数没有自己的this、arguments、super、new.target,它们分别指向外层函数的相应变量。

以前在ES5中使用this有点麻烦,这种问题很常见:

这就需要在嵌套函数外层使用that = this,然后内层使用that,就是下面这样子:

但是现在有了箭头函数,不再需要使用that = this或 _this = this 这种代码啦,因为箭头函数中的this直接就是外层函数中的this,代码更简单了:

4.项目开发过程中,如果要压缩项目中的js文件,可以使用下面的哪个完成?

A  gulp
B  sass
C  requires
D  git
 
正确答案: A
解析:gulp-uglify 为压缩模块
gulp:

gulp 是基于 node 实现 Web 前端自动化开发的工具,利用它能够极大的提高开发效率。

在 Web 前端开发工作中有很多“重复工作”,比如压缩CSS/JS文件。而这些工作都是有规律的。找到这些规律,并编写 gulp 配置代码,让 gulp 自动执行这些“重复工作”。

将规律转换为 gulp 代码

现有目录结构如下:

└── js/
    └── a.js

规律

  1. 找到 js/目录下的所有 .js 文件
  2. 压缩这些 js 文件
  3. 将压缩后的代码另存在 dist/js/ 目录下

编写 gulp 代码

// 压缩 JavaScript 文件
gulp.task('script', function() {
    // 1. 找到
    gulp.src('js/*.js')
    // 2. 压缩
        .pipe(uglify())
    // 3. 另存
        .pipe(gulp.dest('dist/js'));
});

代码执行结果

代码执行后文件结构

└── js/
│   └── a.js
└── dist/
    └── js/
        └── a.js

a.js 压缩前

function demo (msg) {
    alert('--------
' + msg + '
--------')
}

demo('Hi')

a.js 压缩后

function demo(n){alert("--------
"+n+"
--------")}demo("Hi");

此时 dist/js 目录下的 .js 文件都是压缩后的版本。

你还可以监控 js/ 目录下的 js 文件,当某个文件被修改时,自动压缩修改文件。启动 gulp 后就可以让它帮助你自动构建 Web 项目。


gulp 还可以做很多事,例如:

  1. 压缩CSS
  2. 压缩图片
  3. 编译Sass/LESS
  4. 编译CoffeeScript
  5. markdown 转换为 html
关于gulp安装及如何使用请参考:https://www.w3cschool.cn/qtaitm/iasj3ozt.html
sass:

什么是SASS?

SASS(Syntactically Awesome Stylesheet)是一个CSS预处理器,有助于减少CSS的重复,节省时间。它是更稳定和强大的CSS扩展语言,描述文档的样式干净和结构。

历史

它最初由 Hampton Catlin 设计,并于2006年由 Natalie Weizenbaum 开发。后来 Weizenbaum  Chris Eppstein 初始版本用SassScript扩展Sass。

为什么要使用SASS?

  • 它是预处理语言,它为CSS提供缩进语法(它自己的语法)。

  • 它提供了一些用于创建样式表的功能,允许更有效地编写代码和易于维护。

  • 它是超集的CSS,这意味着它包含CSS的所有功能,是一个开源的预处理器,以 Ruby 编码。

  • 它提供了比平面CSS好的结构格式的文档样式。 它使用可重复使用的方法,逻辑语句和一些内置函数,如颜色操作,数学和参数列表。

特征

  • 它是更稳定,强大,与CSS的版本兼容。

  • 它是超集的CSS和基于JavaScript。

  • 它被称为CSS的语法糖,这意味着它使用户更容易阅读或表达的东西更清楚。

  • 它使用自己的语法并编译为可读的CSS。

  • 你可以在更少的时间内轻松地编写CSS代码。

  • 它是一个开源的预处理器,被解释为CSS。

优点

  • 它允许在编程结构中编写干净的CSS。

  • 它有助于编写CSS更快。

  • 它是CSS的超集,帮助设计师和开发人员更有效率和快速地工作。

  • 由于Sass兼容所有版本的CSS,我们可以使用任何可用的CSS库。

  • 可以使用嵌套语法和有用的函数,如颜色操作,数学和其他值。

缺点

  • 开发人员需要时间了解此预处理器中存在的新功能。

  • 如果更多的人在同一个网站上工作,那么将使用相同的预处理器。 有些人使用Sass,有些人使用CSS直接编辑文件。 因此,它将变得难以与现场工作。

  • 有机会失去浏览器的内置元素检查器的好处。

详情参考:https://www.w3cschool.cn/sass/sass_overview.html

requires:

①:require.js是一个js脚本加载器,它遵循AMD(Asynchronous Module Definition)规范,实现js脚本的异步加载,不阻塞页面的渲染和其后的脚本的执行,并提供了在加载完成之后的执行相应回调函数的功能;

②:require.js要求js脚本必须要实现模块化,即文件化;而require.js的作用之一就是加载js模块,也就是js文件。

③:require.js可以管理js模块/文件之间的依赖;即不同的框架例如Jquery,AngularJs等采用了不同的语法,而使用这些语法的js文件在导入时必须排在Jquery.js或Angular.js之后才能顺利执行,require.js则能够解决排序依赖问题。

git:

Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。

详情参考:https://www.runoob.com/git/git-tutorial.html

5.jquery绑定事件的方法有 

A  one
B  bind
C  addEvent
D  on
 
正确答案: A,B,D
解析:addEvent不是一个事件

 jQuery提供了多种绑定事件的方式,每种方式各有其特点,明白了它们之间的异同点,有助于我们在写代码的时候进行正确的选择,从而写出优雅而容易维护的代码。下面我们来看下jQuery中绑定事件的方式都有哪些。

     jQuery中提供了四种事件监听方式,分别是bind、live、delegate、on,对应的解除监听的函数分别是unbind、die、undelegate、off。在开始看他们之前

    一:bind(type,[data],function(eventObject))

      bind是使用频率较高的一种,作用就是在选择到的元素上绑定特定事件类型的监听函数,参数的含义如下:

      type:事件类型,如click、change、mouseover等;

      data:传入监听函数的参数,通过event.data取到。可选;

     function:监听函数,可传入event对象,这里的event是jQuery封装的event对象,与原生的event对象有区别,使用时需要注意

   bind的源码:

1
2
3
4
5
6
7
  bind: function( types, data, fn ) {
 
  return this.on( types, null, data, fn );
 
  }
 
$('#myol li').bind('click',getHtml);

bind的特点就是会把监听器绑定到目标元素上,有一个绑一个,在页面上的元素不会动态添加的时候使用它没什么问题。但如果列表中动态增加一个“列表元素5”,点击它是没有反应的,必须再bind一次才行。要想不这么麻烦,我们可以使用live。

jQuery还有一种事件绑定的简写方式如a.click(function(){});、a.change(function(){});等,它们的作用与bind一样,仅仅是简写而已。

二:live(type, [data], fn)

live的参数和bind一样,它又有什么蹊跷呢,我们还是先瞄一眼源码:

1
2
3
4
5
6
7
live: function( types, data, fn ) {
 
jQuery( this.context ).on( types, this.selector, data, fn );
 
return this;
 
}

可以看到live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。这个context是什么东西呢?其实就是元素的限定范围,看了下面的代码就清楚了:

1
2
3
4
5
$('#myol li').context; //document
 
$('#myol li','#myol').context; //document
 
$('#myol li',$('#myol')[0]); //ol

通常情况下,我们都不会像第三种方式那样使用选择器,所以也就认为这个context通常就是document了,即live方法把监听器绑定到了 document上了。不把监听器直接绑定在元素上,你是不是想起事件委托机制来了呢?若没有,可以点击这里回忆一下。live正是利用了事件委托机制来 完成事件的监听处理,把节点的处理委托给了document。在监听函数中,我们可以用event.currentTarget来获取到当前捕捉到事件的 节点。下面的例子来揭晓:

1
$('#myol li').live('click',getHtml);

三:live存在那样的缺点,所以我们就思考,既然老爷子负担那么重,可不可以别把监听器绑定在document上呢,绑定在就近的父级元素上不就好了。顺应正常逻辑,delegate诞生了。

参数多了一个selector,用来指定触发事件的目标元素,监听器将被绑定在调用此方法的元素上。看看源码:

1
2
3
4
5
delegate: function( selector, types, data, fn ) {
 
return this.on( types, selector, data, fn );
 
}

又是调用了on,并且把selector传给了on。看来这个on真的是举足轻重的东西。照样先不管它。看看示例先:

1
$('#myol').delegate('li','click',getHtml);

看了这么多,你是不是迫不及待想看看这个on的真实面目了呢,这就来:

1
on(type,[selector],[data],fn)

参数与delegate差不多但还是有细微的差别,首先type与selector换位置了,其次selector变为了可选项。交换位置的原因不好查证,应该是为了让视觉上更舒服一些吧。

我们先不传selector来看一个例子:

1
$('#myol li').on('click',getHtml);

可以看到event.currentTarget是li自己,与bind的效果一样。至于传selector进去,就是跟delegate一样的意义了,除了参数顺序不同,其他完全一样。

 

 
原文地址:https://www.cnblogs.com/FD-1909/p/11911834.html