详解valueOf() 与toString()是做什么的以及其在各种情况下的应用

前言

各种引用对象都继承或最终继承于 Object ,使用着Object的原型,所以它们不管何时都有 toString() 和 valueOf() 方法,只不过有些类型的原型重写了这两个方法,比如 Function 实例的原型就重写了 toString() 方法,按照原型链的规则,如果方法和属性在原型链的各原型中有重名,则优先使用最近的方法和属性。


先看看常用的引用类型重写了这两个方法的情况

  • Function 重写了 toString()
  • Date 重写了 toString() 也重写了 valueOf()
  • Array 重写了 toString()
阅读更多

如何实现浏览器内多个标签页之间的通信?

本题主要考察数据存储的知识,数据存储有本地和服务器存储两种方式。这里主要讲解用本地存储方式解决。即调用 localStorage、Cookie等本地存储方式。

第一种 调用localStorage

在一个标签页里面使用 localStorage.setItem(key,value)添加(修改、删除)内容;
在另一个标签页里面监听 storage 事件。
即可得到 localstorge 存储的值,实现不同标签页之间的通信。

标签页1:

<input id="name">  
<input type="button" id="btn" value="提交">  
<script type="text/javascript">  
    $(function(){    
        $("#btn").click(function(){    
            var name=$("#name").val();    
            localStorage.setItem("name", name);   
        });    
    });    
</script>  

标签页2:

<script type="text/javascript">  
    $(function(){   
        window.addEventListener("storage", function(event){    
            console.log(event.key + "=" + event.newValue);    
        });     
    });  
</script>

第二种 调用cookie+setInterval()

将要传递的信息存储在cookie中,每隔一定时间读取cookie信息,即可随时获取要传递的信息。

页面1:

<input id="name">  
<input type="button" id="btn" value="提交">  
<script type="text/javascript">  
    $(function(){    
        $("#btn").click(function(){    
            var name=$("#name").val();    
            document.cookie="name="+name;    
        });    
    });    
</script>

页面2:

<script type="text/javascript">  
    $(function(){   
        function getCookie(key) {    
            return JSON.parse("{\"" + document.cookie.replace(/;\s+/gim,"\",\"").replace(/=/gim, "\":\"") + "\"}")[key];    
        }     
        setInterval(function(){    
            console.log("name=" + getCookie("name"));    
        }, 10000);    
    });  
</script>

sessionStorage 、localStorage 和 cookie 之间的区别

共同点

都是保存在浏览器端,且同源的。

区别

  • cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
  • 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
  • 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  • 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
  • Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
  • Web Storage 的 api 接口使用更方便。

Node.js的版本升级

查看本地node版本

node -v

安装n模块

npm install -g n(mac需要在命令的前面加上sudo)

升级到指定的版本/最新版本,升级之前,可以执行n ls(查看可以升级的版本)

n 8.10.1(版本号)
或者你可以安装最新的稳定版本
n stable

4.安装完成以后,检查一下是否升级成功

node -v

为什么要用setTimeout来模拟setInterval

setTimeout(fn,time): 等待time时间后执行fn
setInterval(fn,time): 每隔time时间执行fn

我们希望setInterval是每隔一段时间自动执行,但是实际应用中,setInterval并不会按照我们预想的那样,它通常存在如下两个缺点。

1. 在执行的时候可能会跳过指定时间间隔
2. 多个定时器函数会立刻执行

我们就实际场景来说一下这两个缺陷

阅读更多

JavaScript里的循环方法:forEach,for-in,for-of

JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的:

for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}

自从JavaScript5起,我们开始可以使用内置的 forEach 方法:

myArray.forEach(function (value) {
  console.log(value);
});

写法简单了许多,但也有短处:你不能中断循环(使用break语句或使用return语句。
JavaScript里还有一种循环方法:for–in。
for-in 循环实际是为循环enumerable对象而设计的:

var obj = {a:1, b:2, c:3};
    
for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}

// 输出:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

你也可以用它来循环一个数组:

for (var index in myArray) {    // 不推荐这样
  console.log(myArray[index]);
}

不推荐用for-in来循环一个数组,因为,不像对象,数组的index跟普通的对象属性不一样,是重要的数值序列指标。
总之,for–in是用来循环带有字符串key的对象的方法。

阅读更多

nodejs 搭建本地服务器 展示文件夹

const express = require('express')
const http = require('http')
const app = express()
const port = 80
var serveIndex = require('serve-index')

app.use(express.static('../'))
app.use(serveIndex('../'))

function getIPAdress() {
    let interfaces = require('os').networkInterfaces()
    for (var devName in interfaces) {
        var iface = interfaces[devName]
        for (var i = 0; i < iface.length; i++) {
            let alias = iface[i]
            if (
                alias.family === 'IPv4' &&
                alias.address !== '127.0.0.1' &&
                !alias.internal
            ) {
                // console.log(alias.address);

                return alias.address
            }
        }
    }
}

var server = http.createServer(app)

server.listen(port, () => {
    console.log(`Example app listening at http://${getIPAdress()}:${port}`)
})

你不知道的浏览器渲染原理

在我们面试过程中,面试官经常会问到这么一个问题,那就是从在浏览器地址栏中输入URL到页面显示,浏览器到底发生了什么?这个问题看起来是老生常谈,但是这个问题回答的好坏,确实可以很好的反映出面试者知识的广度和深度。
本文从浏览器角度来告诉你,URL后输入后按回车,浏览器内部究竟发生了什么,读完本文后,你将了解到:

  • 浏览器内有哪些进程,这些进程都有些什么作用

  • 浏览器地址输入URL后,内部的进程、线程都做了哪些事

  • 我们与浏览器交互时,内部进程是怎么处理这些交互事件的

阅读更多

揭开在线协作的神秘面纱 – OT 算法

相信大家或多或少都有使用过在线文档,国内的像我们在做的 腾讯文档 还有其他家的很多类似产品。今天主要为大家揭开在线协作的神秘面纱,那就是 OT 算法。

背景

在线文档,抽象一下,这些产品的模式都是富文本编辑器+后台,富文本编辑器产生内容,展示内容,然后后台负责保存。
富文本编辑器现在业界已经有很多成熟的产品,像 codeMirror ,这一块本身也是很复杂的一块,也不是咱们这次关注的重点方向。
不知道大家平常在用这些产品的时候有没有思考过一个问题,在线文档编辑的时候产生冲突怎么办?

阅读更多

函数柯里化

柯里化 - 维基百科,自由的百科全书
把接受多个参数函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

柯里化有3个常见作用:

  1. 参数复用
  2. 提前确定
  3. 延迟计算/运行

基本实现

var foo = function(a) {
    return function(b) {
        return a * a + b * b;
    }
}

调用上述函数:(foo(3))(4),或直接foo(3)(4)

阅读更多