1. javascript语言typeof 可能返回的结果
boolean string number undefined object function 共六个
this
- 函数预编译过程this --> window
- 全局作用域里this --> window
- call/apply 可以改变函数运行时this指向
- obj.func(); func()里面的this指向obj
示例代码:
<script>
var name = 222;
var a = {
name : "111",
say : function () {
console.log(this.name);
}
}
var fun = a.say;
fun(); // 222
a.say(); // 111
var b = {
name : "333",
say : function(fun) {
fun();
}
}
b.say(a.say); // 222
b.say = a.say;
b.say(); // 333
</script>
arguments
arguments.callee
指向函数自身引用
func.caller
返回调用指定函数的函数.
<script>
function test () {
demo();
}
function demo () {
console.log(demo.caller)
}
test()
</script>
输出结果:
ƒ test () {
demo();
}
严格模式下不能使用
"use strict"
面试题:
<script>
var foo = 123;
function print() {
this.foo = 234;
console.log(foo); // 234
}
print();
</script>
<script>
var foo = 123;
function print() {
// var this = Object.create(print.prototype)
this.foo = 234;
console.log(foo); // 123
}
new print();
</script>
克隆
浅层克隆
var obj = {
name : 'abc',
age : 123,
sex : 'female',
}
var obj1 = {}
function clone(origin, target) {
var target = target || {};
for(var prop in origin) {
target[prop] = origin[prop];
}
return target
}
clone(obj, obj1);
深层克隆
<script>
var obj = {
name : 'abc',
age : 123,
card : ['visa','master'],
wife : {
name : "bcd",
son : {
name : "aaa"
}
}
}
var obj1 = {}
function deepClone(origin, target) {
var target = target || {},
toStr = Object.prototype.toString,
arrStr = "[object Array]";
for(var prop in origin) {
if(origin[prop] !== "null" && origin.hasOwnProperty(prop)) {
if(typeof(origin[prop]) == 'object') {
// if(toStr.call(origin[prop]) == arrStr) {
// target[prop] = [];
// }else{
// target[prop] = {};
// }
target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {}
deepClone(origin[prop], target[prop])
}else{
target[prop] = origin[prop]
}
}
}
return target
}
deepClone(obj, obj1)
</script>
数组
数组的定义:
- new Array(length/content);
- 字面量
<script>
var arr1 = [1,2,3,4];
var arr2 = new Array(1,2,3,4);
var arr3 = new Array(10);
</script>
输出结果:
数组的读和写
js数组几乎没有什么报错
- arr[num] // 不可以溢出读,结果undefined
- arr[num] = xxx; // 可以溢出写
数组常用的方法 ES3.0
- 改变原数组
push, pop, shift, unshift, sort, reverse
splice
push实现:
<script>
var arr = [1,2,3];
Array.prototype.push = function() {
for(var i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return this.length;
}
</script>
unshift:在数组前面插入数据
shift: 在数组前面拿出数据
sort: 对数组的元素进行排序
<script>
// 1. 必须写两形参
// 2. 看返回值 1)当返回值为负数时,那么前面的数放在前面
// 2) 为正数, 那么后面的数放在前面
// 3) 为0, 不动
var arr = [1,7,3,4,19];
arr.sort(function(a,b) {
// return a-b; //升序
return b-a; // 降序
})
</script>
reverse:将数组顺序取反
splice : arr.splice(从第几位开始,截取多少的长度,在切口处添加新的数据) 返回截取的片段
注意:数组一般都是有负数的,原理如下:
<script>
var arr = [1,2,3,5];
console.log(arr.splice(-1,1)); // 5
// 简写
splice = function (pos) {
pos += pos > 0 ? 0 : this.length; // -1 + 4 =3
}
</script>
给一个有序数组,乱序
<script>
// 给一个有序数组,乱序
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(function() {
return Math.random() - 0.5;
})
</script>
-
不改变原数组
concat, join --> split, toString, sliceconcat 拼接数组
slice (从该位开始截取,截取到该位)
<script>
var arr = [1,2,3,4,5,6];
var newArr = arr.slice(1,3);
var newArr1 = arr.slice(1);
console.log(newArr); // [2, 3]
console.log(newArr1); // [2, 3, 4, 5, 6]
</script>
join 用参数连接数组值
<script>
var arr = [1,2,3,4,5,6];
var newArr = arr.join('-');
var newArr1 = arr.join('呵呵');
console.log(newArr); // 1-2-3-4-5-6
console.log(newArr1); // 1呵呵2呵呵3呵呵4呵呵5呵呵6
</script>
split 把一个字符串分割成字符串数组。
类数组
- 可以利用属性名模拟数组的特性
- 可以动态的增长length属性
- 如果强行让类数组调用push方法,则会根据length属性值的位置进行属性的扩充。
条件:属性要为索引(数字)属性,必须有length属性,最好加上push
<script>
var obj = {
"0" : "a",
"1" : "b",
"2" : "c",
name : "abc",
age : 123,
length : 3,
push : Array.prototype.push,
splice : Array.prototype.splice
}
</script>
题目:
- 封装type
<script>
function type(target) {
var ret = typeof(target);
var template = {
"[object Array]" : "array",
"[object Object]" : "boject",
"[object Number]" : "number - object",
"[object Boolean]" : "boolean - object",
"[object String]" : "string - object"
}
if(target === null ) {
return 'null';
}
if (ret == 'object') {
var str = Object.prototype.toString.call(target);
return template[str];
}else{
return ret;
}
}
</script>
- 数组去重,要求在原型链上编程
方法一:
<script>
var arr = [1,1,2,3,2,3,4,3,4,5];
Array.prototype.unique = function() {
var temp = {},
arr = [],
len = this.length;
for(var i = 0; i < len; i++) {
if(!temp[this[i]]) {
temp[this[i]] = "abc";
arr.push(this[i]);
}
}
return arr;
}
console.log(arr.unique()) ; // [1, 2, 3, 4, 5]
</script>
注意:
一旦经历了var的操作,所得出的属性,window,这种属性叫做不可配置的属性
不可配置的属性delete不掉
面试题:
- 一个字符串[a-z]组成,请找出该字符串第一个只出现一次的字母;
<script>
var str = "dslgaihggfdlgjirnbldfzgfdghdfgsd"
// 字符串去重
var str1 = [].filter.call(str,(s,i,o) => o.indexOf(s) == i);
console.log(str1); // ["d", "s", "l", "g", "a", "i", "h", "f", "j", "r", "n", "b", "z"]
for(var i in str1) {
var num = 0;
for(var j=0; j < str.length; j++) {
if(str1[i] == str[j]) {
num ++;
}
}
if(num ==1){
console.log(str1[i])
break
}
}
</script>
- 字符串去重;
<script>
var str = "fagrhsafaerefs";
// es6的函数写法
var str1 = [].filter.call(str,(s,i,o)=>o.indexOf(s)==i).join('');
// var str2 = [].filter.call(str,function(s,i,o){return o.indexOf(s)==i;}).join('');
console.log(str2);
</script>
核心思想为使用数组的filter方法过滤掉除第一次出现的字符以外其它字符,然后join连接字符串,s、i、o 3个参数分别为:当前字符、当前字符索引、原字符串
此方法妙处在于利用js的call方法改变宿主,使用字符串调用数组中的过滤方法(字符串无此方法),减少了复杂的循环步骤;并且此方法没有使用多余的变量减少内存开支;巧妙的利用indexOf取出字符串中第一次出现的字符(非第一次出现的字符被过滤掉)。因而实现此需求。