宽松相等 & 严格相等
-
宽松相等
const a = { value : 0 }; a.valueOf = function() { return this.value += 1; }; console.log(a == 1 && a == 2 && a == 3); // true注意: 宽松相等 == 会先将左右两两边的值转化成相同的原始类型,然后再去比较他们是否相等。 在转化之后( == 一边或两边都需要转化),最后的相等匹配会像 === 符号一样去执行判断。 宽松相等是可逆的,对于任何值 A 与 B,通常 A == B 与 B == A 具有相同的表现(除了转换的顺序不同)。
ToPrimitive(input, PreferredType?)可选参数 PreferredType 可以指定最终转化的类型,它可以是 Number 类型或 String 类型, 这依赖于 ToPrimitive() 方法执行的结果返回的是 Number 类型或 String 类型
-
严格相等
var value = 0; //window.value Object.defineProperty(window, 'a', { get: function() { return this.value += 1; } }); console.log(a===1 && a===2 && a===3) // true -
类型固定时,宽松相等 与 严格相等
var value = 0; const a = { get: function() { return this.value += 1; } } console.log((0, a.get)() == 1 && (0, a.get)() == 2 && (0, a.get)() == 3); // true console.log((0, a.get)() === 1 && (0, a.get)() === 2 && (0, a.get)() === 3); // true -
Object.defineProperty
-
语法
Object.defineProperty(obj, prop, descriptor)
-
参数
obj 用于定义属性的对象。
prop Symbol要定义或修改的名称或 属性。
descriptor 正在定义或修改属性的描述符。
-
返回值
传递给函数的对象
-
-
参考链接
React中click事件对比
-
1、使用匿名函数绑定onClick
<button onClick={(e) => { alert('我点击了按钮') }} >按钮</button>特点: 由于onClick使用的是匿名函数,所以每次重渲染的时候,会把该onClick当做一个新的prop来处理,会将内部缓存的onClick事件进行重新赋值。
-
2、使用箭头函数方法绑定onClick
onClick = (e) => { alert('我点击了按钮'); } ... <button onClick={this.onClick}>按钮</button> -
3、内部声明的不是箭头函数,使用bind绑定上下文
onClick(e) { alert('我点击了按钮'); } ... <button onClick={this.onClick.bind(this)}>按钮</button>特点:该方法的效果与第一种匿名函数差不多,因为bind会返回新的函数,也会被react认为是一个新的prop。
事件流
-
事件流分为两种,捕获事件流和冒泡事件流。
- 捕获事件流从根节点开始执行,一直往子节点查找执行,直到查找执行到目标节点。
- 冒泡事件流从目标节点开始执行,一直往父节点冒泡查找执行,直到查到到根节点。
-
事件流分为三个阶段,一个是捕获节点,一个是处于目标节点阶段,一个是冒泡阶段。
函数A和函数B,实现B继承A
-
方法
// 方式1 function B() {} function A() {} B.prototype = new A(); // 方式2 function A() {} function B() { A.call(this); } // 方式3 function B() {} function A() {} B.prototype = new A(); function B() { A.call(this); } -
特点
方式1:简单易懂,但是无法实现多继承,父类新增原型方法/原型属性,子类都能访问到
方式2:可以实现多继承,但是只能继承父类的实例属性和方法,不能继承原型属性/方法
方式3:可以继承实例属性/方法,也可以继承原型属性/方法,但是示例了两个A的构造函数
-
参考链接
浏览器窗口大小改变
-
window.onresize
直接给window的onresize属性绑定事件,只能有一个。也就是说后面的会覆盖前面
window.onresize = function() { console.log('操作1'); } window.onresize = function() { console.log('操作2'); }当浏览器窗口大小发生改变时,只会输出'操作2'
-
$(window).resize
-
作用
当调整浏览器窗口的大小时,发生 resize 事件。可以写多个 $(window).resize 方法
resize() 方法触发 resize 事件,或规定当发生 resize 事件时运行的函数。
$(window).resize(function(){ console.log("操作3") }); $(window).resize(function(){ console.log("操作4") });当浏览器窗口大小发生改变时,会输出'操作3' '操作4'
浏览器窗口大小改变时,这段代码会执行多次,有时我们可能想要处理比较复杂的逻辑,会对性能影响较大,这样就比较容易造成浏览器假死。
如何实现不管窗口如何改变,只在停止改变之后才执行代码呢?
var resizeTimer = null; $(window).bind('resize', function (){ if (resizeTimer) clearTimeout(resizeTimer); resizeTimer = setTimeout(function(){ console.log("窗口发生改变了哟!"); } , 100); });通过增加定时器的方式来让代码延迟执行,这样每次窗口改变的时候,我们都清除事件,只有当他停下来之后,才会继续执行。
-
使用
触发 resize 事件 $(selector).resize()
将函数绑定到 resize 事件 $(selector).resize(function)
-
指定页面返回最顶部
-
1、jquery
$('html, body').animate({scrollTop: 0}, 1000); -
2、使用a标签锚点定位
<a href="#toTop" target="_self">返回顶部</a> -
3、使用JS scrollTo 函数
-
javascript scroll 函数(scrollBy scrollTo)是用来滚动页面到指定位置,格式定义如下:
■scrollBy(xnum,ynum) ■scrollTo(xpos,ypos) -
其中:
■xnum,ynum 分别指水平、垂直滚动多少像素,正值表示向右或向下滚动,负值表示向左或向上滚动
■xpos,ypos 分别指水平和垂直坐标
-
示例:
<a href="javascript: scrollTo(0, 0);">返回顶部</a>
-
-
4、scrollBy 慢速滚动返回顶部
本方式使用上面提到的 scrollBy 函数,每次只滚动定量像素,整体看起来有点滚动效果,代码如下:
- 代码如下:
var sdelay = 0; function returnTop() { window.scrollBy(0, -100); // Only for y vertical-axis if(document.body.scrollTop > 0) { sdelay = setTimeout('returnTop()', 50); } } || var top = document.body.scrollTop || document.documentElement.scrollTop scrollBy(0,-top); } - scrollBy 函数第二个参数我设了-100,越大(比如-10)滚动越慢,越小滚动越快,启动滚动只需在页面底部加个链接:
<a href="javascript:returnTop();">返回顶部</a>
- 代码如下:
-
5、scrollTop
scrollTop 属性表示被隐藏在内容区域上方的像素数。元素未滚动时,scrollTop 的值为0, 如果元素被垂直滚动了,scrollTop 的值大于0,且表示元素上方不可见内容的像素宽度
由于 scrollTop 是可写的,可以利用 scrollTop 来实现回到顶部的功能
document.body.scrollTop = document.documentElement.scrollTop = 0;
- 6、scrollIntoView()
Element.scrollIntoView方法滚动当前元素,进入浏览器的可见区域
该方法可以接受一个布尔值作为参数。 如果为true,表示元素的顶部与当前区域的可见部分的顶部对齐(前提是当前区域可滚动); 如果为false,表示元素的底部与当前区域的可见部分的尾部对齐(前提是当前区域可滚动)。 如果没有提供该参数,默认为true
使用该方法的原理与使用锚点的原理类似,在页面最上方设置目标元素,当页面滚动时,
目标元素被滚动到页面区域以外,点击回到顶部按钮,使目标元素重新回到原来位置,则达到预期效果
document.getElementById('target').scrollIntoView();
jQuery.extend( [deep ], target, object1 [, objectN ] );
-
描述: 将两个或更多对象的内容合并到第一个对象
[deep ] 取值true/false,表示是否为深拷贝,默认为false(浅拷贝)
target {} 目标对象
object1 第一个被合并的对象
objectN 第N个被合并的对象
let state = { id: 1111, list: [ { id: 0, name: 'name0' }, { id: 1, name: 'name1' } ] } let data = { list: [ { id: 0, name: 'name2' } ] } <!-- 结果进行了合并 --> $.extend(true, {}, state, data); // {id: 1111, list: [{id: 0, name: 'name2'},{id: 1, name: 'name1'}]}
es6 class 的 new 实例和 es5 的 new 实例有什么区别
下面是摘自 阮一峰翻译的 《ECMAScript 6 入门》中 “Class 的基本用法”
-
ES5 Class 与 ES6 生成类的实例对象一样,使用
new命令ES5 写法:
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; // 使用 new var p = new Point(1, 2); // {x: 1, y: 2} p.toString(); // (1, 2)ES6 写法:
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } // 使用 new let point = new Point(1, 2); point.toString() // (1, 2) -
类的内部所有定义的方法,都是不可枚举的(non-enumerable)
-
采用 ES5 的写法,
toString方法就是可枚举的
__proto__ 与 prototype 的区别
- 使用 ES6 中的 Class 生成类的实例
class Point {
constructor() {}
}
let point = new Point();
// 以下三种结果一致
Point.__proto__.__proto__
Point.prototype.__proto__
point.__proto__.__proto__
/*
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
*/
- 函数与对象的
__proto__一样
var func = function () {};
var obj ={};
console.log(func.__proto__.__proto__)
console.log(obj.__proto__)
js 中所有的对象都有__proto__属性,只有function具有prototype属性。