js A

ajax请求的过程 ?

// 1.创建ajax对象
var xhr = null;
if(window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
} else {
    //为了兼容IE6
    xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

// 2.连接服务器
// 连接服务器open(方法GET/POST,请求地址, 异步传输)
xhr.open('GET',  'data.txt',  true);

// 3.发送请求
xhr.send();

// 4.接收返回数据
/*
** 每当readyState改变时,就会触发onreadystatechange事件
** readyState属性存储有XMLHttpRequest的状态信息
** 0 :请求未初始化
** 1 :服务器连接已建立
** 2 :请求已接受
** 3 : 请求处理中
** 4 :请求已完成,且相应就绪
*/
xhr.onreadystatechange = function() {
    if(xhr.readyState == 4) {
        /*
        ** Http状态码
        ** 1xx :信息展示
        ** 2xx :成功
        ** 3xx :重定向
        ** 4xx : 客户端错误
        ** 5xx :服务器端错误
        */
        if(xhr.status == 200) {
            success(xhr.responseText);
        } else {
            if(failed) {
                failed(xhr.status);
            }
        }
    }
}

DOM事件流 ?

传递方向:先自顶向下(capture阶段), 再自下而上(bubble阶段),即先执行捕获类型的事件,再执行冒泡类型的事件,最后执行浏览器默认行为。

参考1

js原型 ?

function Person () {}
var person = new Person();
  • JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的构造函数的原型对象,person._proto_ == Person.prototype。
  • 每个对象都有__proto__属性,但只有函数对象才有 prototype 属性
  • 所有对象的__proto__都指向其构造器的 prototype,如[]._proto_== Array.prototype。
  • person 是 Person 的一个实例,构造函数的原型 Person.prototype,也是 Person 的一个实例。 实例的构造器就是 Person,=>

person.constructor == Person,

Person.prototype.constructor == Person,

person._proto_ == Person.prototype。

  • 所有函数对象__proto__都指向 Function.prototype,它是一个空函数。
  • Function.prototype 是唯一一个typeof XXX.prototype为“function”的prototype,其他的都是“object”。

参考: 123

继承 ?

es6继承

function Hello(name) {
  this.name = name;
}

Hello.prototype.hello = function hello() {
  return 'Hello ' + this.name + '!';
};

Hello.sayHelloAll = function () {
  return 'Hello everyone!';
};

function HelloWorld() {
  Hello.call(this, 'World');
}

HelloWorld.prototype = Object.create(Hello.prototype);
HelloWorld.prototype.constructor = HelloWorld;
HelloWorld.sayHelloAll = Hello.sayHelloAll;

HelloWorld.prototype.echo = function echo() {
  alert(Hello.prototype.hello.call(this));
};

var hw = new HelloWorld();
hw.echo();

alert(Hello.sayHelloAll());

js 类型及其判断 ?

数据类型

  • 基本数据类型:原始数据类型,包括undefined、null、Boolean、Number、String、Symbol (ES6新增,表示独一无二的值)。
  • 引用数据类型:统称为Object对象,主要包括对象、数组和函数。
  • 基本类型值的比较:
    • == 只进行值的比较,会进行数据类型的转换。
    • ===不仅进行值得比较,还要进行数据类型的比较。
  • 引用类型值的比较:是引用的比较
  • 存储位置:基本类型存放在栈区,引用类型同时保存在栈和堆中,其指针存在栈区,指针指向堆中该实体的起始地址。

类型判断

typeof

typeof返回一个表示数据类型的字符串,返回结果包括:'number'、'boolean'、'string'、'symbol'、'object'、'undefined'、'function'等7种数据类型, 但不能判断null、array、Date、RegExp。

    typeof Symbol(); // symbol 有效
    typeof ''; // string 有效
    typeof 1; // number 有效
    typeof true; //boolean 有效
    typeof undefined; //undefined 有效
    typeof new Function(); // function 有效

    typeof null; //object 无效
    typeof [] ; //object 无效
    typeof new Date(); //object 无效
    typeof new RegExp(); //object 无效

数组和对象返回的都是object,这时就需要使用instanceof来判断。

instanceof

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

    [] instanceof Array; //true
    {} instanceof Object;//true
    new Date() instanceof Date;//true
    new RegExp() instanceof RegExp//true

constructor

    var aa=[1,2];
    console.log(aa.constructor===Array);//true
    console.log(aa.constructor===RegExp);//false
    console.log((1).constructor===Number);//true

    var reg=/^$/;
    console.log(reg.constructor===RegExp);//true
    console.log(reg.constructor===Object);//false

Object.prototype.toString.call()

Object.prototype.toString.call() 最准确最常用的方式。首先获取Object原型上的toString方法,让方法执行,让toString方法中的this指向第一个参数的值。

    Object.prototype.toString.call('');   // [object String]
    Object.prototype.toString.call(1);    // [object Number]
    Object.prototype.toString.call(true); // [object Boolean]
    Object.prototype.toString.call(undefined); // [object Undefined]
    Object.prototype.toString.call(null); // [object Null]
    Object.prototype.toString.call(new Function()); // [object Function]
    Object.prototype.toString.call(new Date()); // [object Date]
    Object.prototype.toString.call([]); // [object Array]
    Object.prototype.toString.call(new RegExp()); // [object RegExp]
    Object.prototype.toString.call(new Error()); // [object Error]
    Object.prototype.toString.call(document); // [object HTMLDocument]
    Object.prototype.toString.call(window); //[object Window] window是全局对象global的引用

注意点

  • instanceof 三大弊端:
    • 对于基本数据类型来说,字面量方式创建出来的结果和实例方式创建的是有一定的区别的
        console.log(1 instanceof Number)//false
        console.log(new Number(1) instanceof Number)//true
    
    • 只要在当前实例的原型链上,我们用其检测出来的结果都是true。在类的原型继承中,我们最后检测出来的结果未必准确。
        var arr = [1, 2, 3];
        console.log(arr instanceof Array) // true
        console.log(arr instanceof Object);  // true
        function fn(){}
        console.log(fn instanceof Function)// true
        console.log(fn instanceof Object)// true
    
    • 不能检测null 和 undefined,对于特殊的数据类型null和undefined,他们的所属类是Null和Undefined,但是浏览器把这两个类保护起来了,不允许我们在外面访问使用。 从 Object.prototype.toString.call(null); // [object Null] 可以看出。 但可以这样
        //判断null
        var a = null;
        typeof a // "object";
        a === null // true;
    
        //判断undefined
        var b = undefined;
        typeof b === 'undefined'; // true
        b === undefined // true;
    
  • constructor 两大弊端:
    • null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
    • 函数的 constructor 是不稳定的,这个主要体现在把类的原型进行重写,在重写的过程中很有可能出现把之前的constructor给覆盖了,这样检测出来的结果就是不准确的。

参考 1

跨域 ?

  • 跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。

解决跨域常用方案:

  • jsonp (JSON with Padding) 只支持GET请求
  • CORS (Cross-origin resource sharing) 跨域HTTP请求的根本解决方案
  • postMessage
  • websocket
  • Node中间件代理
  • nginx反向代理
  • window.name + iframe
  • location.hash + iframe
  • document.domain + iframe 只能用于二级域名相同的情况

参考 12

欢迎关注

赏不赏,看您心情