【JavaScript】学习笔记-内置对象与常用方法

(这篇笔记是在2015年初学时记的,可能有错误)

JavaScript内置对象简介

本文介绍Js中13种标准内置对象,全是边听课件边整理的,内容不免有些繁杂不细致,权当笔记。

JavaScript的标准内置对象分为两类。

构造器对象:

Object
Boolean
String
Number
Function
Array
RegExp
Date
Error

其他对象:

Math
JSON
全局对象

Object

  • 构造器说明
    Object是一组属性和方法的集合
    String/Number/Boolean/Array/Date/Error构造器都是Object子类对象,继承Object源性对象属性和方法。
  • 实例化对象方法
    var obj = new Object({name: 'jerry', age: 0});
    var obj = {name: 'jerry', age: 0};
  • 属性、方法
    Object构造器提供了一系列的prototype,create,keys...等方法
    其中prototype就是原型对象,有以下方法。
constructor
toString
valueOf
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString

构造器的原型对象在对象实例化时将会被添加到实例对象的原型链上去。比如说通过var obj = new Object();定义了obj这样一个对象,就会生成proto: Object这样一个原型链,它不能被显式的调用。但是,我们定义的对象可以调用原型链上的一系列方法。用上述方法new出来的obj这样一个实例对象只有他的原型链属性_proto_: Object,没有其他的属性,因此,Object构造器没有实例对象属性、方法。

Object.create

  • 功能
    基于原型对象创建新对象
  • 语法
    Object.create(proto[propertiesObject])
  • 范例
var proto = {a:1,b:2};
var obj = Object.create(proto);

在调试器中可以看出,obj对象在原型链上有a,b两个属性。

Object.prototype.toString

  • 功能
    获取方法调用者的标准类型
  • 语法
    objectObj.toString()
  • 范例
var obj = {};
obj.toString();//"[object Object]"

Object.protorype.hasOwnProperty

  • 功能
    判断一折属性是否是对象自身属性
  • 语法
    objectObj.hasOwnProperty(prop)
  • 范例
var obj = Object.create({a:1,b:2});
obj.c = 1;
obj.hasOwnProperty("c"); //true
obj.hasOwnProperty("a"); //false

这说明hasOwnProperty可以判断一个属性是对象自身的属性还是原型链上的属性。

Boolean

  • 构造器
    值:true,false
  • 出现场景
    条件语句导致系统指定的隐式类型转换
    if ( document.getElementById('notExistElement') ) {...}else{...}
    这里用getElementById方法去获取对象一个并不存在的属性的时候,它会返回null或一个对象,当它返回null时,系统会自动将null值转化为布尔值,然后交给if语句进行判断。
  • 显式定义
true //可以直接用true或者false这样的变量
var a = true;
var a = new Boolean(false);//或者用new布尔构造器来定义一个布尔的引用对象
  • 构造器对象属性、方法
    只有一个属性prototype
  • 原型对象属性、方法
    原型对象上有以下方法:
constructor
toString
valueOf
  • 其他类型向布尔类型转换
数字→布尔 只有0,NaN转换为false
字符串→布尔 只有空字符串为false
undefined→布尔 undefined都为false
null→布尔 null都为false
对象→布尔 对象都为true

String

  • 构造器对象说明
    由单引号或双引号括起来的字符序列
  • 字符串使用
"" //空字符串
'hello world!'
var s = 'name="myform"';
var s = new String("hello world!");//创建对象

-构造器对象属性、方法

prototype
fromCharCode //可以实现将ASCII码转换为字符串的功能
  • 原型对象属性、方法
    String对象有以下方法:
constructor
indexOf
replace
slice
split
charCodeAt
toLowerCase

String.prototype.indexOf

  • 功能
    获取子字符串在字符串中位置索引
  • 语法
    stringObj.indexOf(serchvalue,fromindex)
    第一个参数是搜索的字符串,第二个参数是搜索的起始位置,返回值是个索引
  • 范例
var str = "welcome to NetEase!welcome to MOOC!";
var idx = str.indexOf("to"); //没有起始位置时从头开始查找,并返回"to"所在的索引位置'8'
str.indexOf("to", idx+1); // 27
str.indexOf("To"); // 查找不存在的字符串时会返回'-1'

String.prototype.replace

  • 功能
    查找字符串替换成目标字符
  • 语法
    stringObj.replace(regexp/substr,replacement)
    第一个参数是个子字符串或正则表达式,第二个参数是个目标字符串
  • 范例
    如要将"1 plus 1 equal 3"变换为"2 plus 1 equal 3",使用以下语句即可。
var str = "1 plus 1 equal 3";
str = str.replace("1","2");

如要把"2 plus 1 equal 3"变换为"2 dollor plus 1 dollor equal 3 dollor",可以在上述代码的基础上修改为:

var str = "1 plus 1 equal 3";
str = str.replace("1","2");
str.replace(/\d+/g,"$& dollor");

String.prototype.split

  • 功能
    按分隔符将字符串分割成字符串数组
  • 语法
    stringObj.split(separator,howmany)
    第一个参数是一个分割符,第二个参数是数组长度。
  • 范例
var str = "1 plus 2 equal 3";
str.split(" ");

这样,该字符串会被分割为["1","plus","2","equal","3"]这样一个长度为5的字符串数组。

var str = "1 plus 2 equal 3";
str.split(" ", 3);

这样会分割为`["1","plus","2"]这样的长度3的字符串数组。

var str = "1 plus 2 equal 3";
str.split(/\d+/);

这样会分割为[""," plus "," equal ",""]

Number

  • 构造器对象说明
    整形直接量,八进制(-0)直接量,十六进制(0x-)直接量,浮点型直接量。
  • 数字对象的使用
10;
1.2e5;
var count = 0x10;
var pi = new Number(3.14);
  • 构造器对象属性、方法
prototype
MAX_VALUE
MIN_VALUE
NaN
NEGATIVE_INFINITY
POSITIVE_INFINITY
  • 原型对象属性、方法
constructor
toFixed
toExponential

Number.prototype.toFixed

  • 功能
    把Number四舍五入为指定小数位数的数字
  • 语法
    numberObj.toFixed(num)
    其中,num是要指定的小数位数。
  • 范例
var num = 13.37;
num.toFixed(1);

这样会把13.37转化为13.4。

Array

  • 构造器对象说明
    用于定义数组对象
  • 创建数组
    常用的创建数组方法如下。
var a = [1,"abc", true, function(){}];
var a = new Array();
var a = new Array(1, "abc", true);
  • 构造器对象属性、方法
    paototypeisArray
    isArray用于判断一个对象是否是数组。
  • 原型对象属性、方法
constructor
splice
forEach
find
concat
pop
push
reverse
shift
slice
  • 实例对象属性、方法
    Array类型的实例对象都会有一个length的属性,用它获取数组的实际长度。

array堆栈操作

var colors = new Array();
var count = colors.push("red","green");
alert(count);
count = colors.push("black");
alert(count);
var item = colors.pop();
alert(item);
alert(colors.length);

简要的以这段代码为例看一下js堆栈操作的方法。

.push 压栈

.push方法后可以接多个参数,该方法会将参数压入调用该方法的数组中,返回压栈成功的值数。

.pop 取栈

.pop方法会将数组所在栈中的最后一个元素取出,并返回取出的这个值。

.shift 队列操作

.shift方法会将数组所在栈排在最前面的元素取出,并返回取出的这个值。

.sort 排序

.sort方法不接受参数时默认将一个数组中的元素依次从小到大排序。
如果想让.sort方法将数组中元素从大到小排序需要自己写一个比较的函数,如下:

function compare(value1, value2){
    if(value1 < value2){
        return 1;
    } else if(value1 > value2){
        return -1;
    } else {
        return 0;
    }
}
var values = [2, 5, 4, 15, 23];
values.sort(compare);

将这个函数作为一个值当做.sort方法即可。

.reverse 颠倒数组顺序

如描述,.reverse()的方法会让一个数组顺序颠倒。

.concat 连接

如果要将数组和某些元素连接起来可以用.concat方法:
colors = colors.concat("yellow",["black","brown"]);
这样colors后面就接上了yellow,black,brown。

.slice 截取

.slice接受1~n个参数。
如果只输入了一个参数,就会将这个参数之前的元素全部截掉。
如果输入了两个参数,会将这两个参数之间的元素记录下来并返回。
在数组调用。参数1表示数组第一个元素,-1表示倒数第一个元素,以此类推。
请注意,该方法并不会修改数组,而是返回一个子数组.如果想删除数组中的一段元素,应该使用方法 Array.splice()。

Array.protorype.splice 删除并插入元素

  • 功能
    从数组中删除或添加元素,返回被删除的元素列表。

  • 语法
    arrayObj.splice(start,deleteCount[,item1[,item2,…]]])
    .splice后接受1~3个参数,会修改本数组,返回值为删除的所有元素。
    第一个参数表示从第几个开始删除元素,只填第一个参数会删去这个参数所代表的元素之后的所有元素。
    第二个参数表示从第一个参数的起始点开始要删除几个元素,不填第三个参数使.splice方法只具有删除元素的功能。
    第三个及之后的参数表示从第一个参数开始的位置要依次向数组中插入的内容。

    var arr = ["1","2","a","b","6"];
    var ret = arr.splice(2,2,"3","4","5");
    arr;
    在这里,将arr数组从"a"开始删除了两个元素,并在相应位置添加了三个元素"3","4","5"。该方法返回了被删除的元素数组并赋给ret,相应的,arr数组被更改为["1","2","3","4","5","6"].

Array.prototype.forEach

  • 功能
    遍历数组元素并调用回调函数。
  • 语法
    arrayObj.forEach(callback[,thisArg])这里的callback是一个回调函数。
    回调函数定义如下:
function callback(value, index, arrayObject){……}

它有三个参数。第一个参数是当前数组的元素值,第二个参数是当前元素的索引(第几个数),第三个参数是包含该元素的数组对象本身。

  • 范例
function logArray(value, index, array)
{
    console.log(value);
    console.log(value === array[index]);
}
[2, 5, , 9].forEach(logArray);

此时,它的运行结果在F12的console里是:

2
true //第一次循环
5
true //第二次循环
9
true //第三次循环

它执行了三次回调,直接将空元素摒除掉了。引用回调函数时并不需要写上其所需要的三个参数,可以直接用,但是函数的定义中三个参数缺一不可。

Function

  • 构造器说明
    用于定义函数或者新对象构造器。
  • 实例化函数方法

1.对象实例化方法,使用new+function构造器创建一个函数add:
var add = new Function("i","j","return(i+j)");
2.更简单的函数关键字语句方法,直接用function关键字定义函数:
function add(i, j) { return i + j;}
3.用函数表达式的方法,也就是去掉new。
var add = function(i, j) { return i+j;};

与C、C++、Java不同,Js的函数可以当做一个变量使用。它可以被赋值和被当做参数传递,以及被当做返回值返回。

  • 属性、方法
    函数比较重要的只有prototype方法。
  • 原型对象属性、方法
    有:
constructor
apply
call
bind
  • 实例对象属性、方法
    有两个实例对象属性L:lengthprototype。从这里可以看出,function构造器与其他普通构造器的区别,function构造器构造出来的实例对象本身也有prototype属性,因为function构造器构造出来的对象是函数,它仍然可以被当做构造器使用,在function函数执行时,它还会有argumentscaller这样一系列的属性。在谈到具体的function原型对象、方法之前,先来了解一下如何自定义对象构造器。

自定义对象构造器

function Point(x, y){
    this.x = x;
    this.y = y;
}

这里通过function关键字定义了一个Point对象构造器,这里的this.x
、this.y表示用Point构造器构造出来的实例对象有x和y这样两个属性。

Point.prototype.move = function(x, y){
    this.x += x;
    this.y += y;
}

这里为Point的原型对象添加了自定义的属性,这里添加了一个move方法。构造器对象与普通对象相比有一个prototype属性,这表明构造器对象可以生成其他对象。
用new Point实例化一个对象var p = new Point(0,1);
p这个对象有两个自身属性,x、y,它的原型链上有move这样一个方法。下面来说function原型中几个重要的方法。

Function.prototype.apply

  • 功能
    通过参数指定函数调用者和函数参数并执行该函数
  • 语法
    functionObj.apply(thisArg,[argsArray])
    第一个参数需要指定该函数的调用者。第二个参数是一个传递给该函数的参数列表。
  • 范例
Object.prototype.toString.apply("123");

这个例子中使用字符串"123"去调用字符串toString,它的返回值是[object String]。当参数中函数的调用者缺省的时候,只使用参数列表中的元素去调用其prototype.后的函数。来看一个复杂点的例子。

    function Point(x, y){
    this.x = x;
    this.y = y;
    }
    Point.prototype.move = function(x, y){
    this.x += x;
    this.y += y;
    }
    var p = new Point (0, 0);
    p.move(2,2);
    var circle = {x:1, y:1, r:1};
    p.move.apply(circle, [2, 1]);

这样,circle中的元素就变为了{x: 3, y:2, r: 1}

Function.prototype.bind

  • 功能
    通过参数指定函数调用者和函数参数但是并不执行,只是返回该函数引用。
  • 语法
    functionObj.bind(thisArg[,arg1[,arg2[,…]]])
    bind的函数调用者是一个函数,第一个参数是我们想指定的该函数的调用者,后面是一个函数的参数列表。
  • 范例
function Point(x, y){
    this.x = x;
    this.y = y;
}
Point.prototype.move = function(x, y){
    this.x += x;
    this.y += y;
}
var p = new Point(0,0);
var circle = {x:1, y:1, r:1};
p.move.apply(circle,[2,1]);//这里可以用上面的方法执行移动
//但是,如果想实现让该圆在一定时间后再移动,可以用到下面这种方法:

var circlemove = p.move.bind(circle, 2, 1);
setTimeout(circlemove, 1000);

这样就把带参数的circle引用绑定给一个函数circlemove,然后用setTimeout的方式去设置在1秒后执行该函数引用,以此来达到目的。

子类构造器

上面的例子中,circle使用的是Point函数的原型方法move来进行的移动功能,下面介绍用子类继承的方法来实现circle这样功能的构造器,最后实现圆的移动。
首先,通过function关键字来定义Circle构造器。

function Circle(x, y, r){
    Point.apply(this, [x, y]);
    this.radius = r;
}
//此时可以把Circle的原型对象指定为Point的实例对象。
Circle.prototype = new Point();
delete Circle.prototype.x;
delete Circle.prototype.y;
//这样,原型链属性上有一个move方法,上面这3句话也可以简化为Object.create这样的一种方法去实现.将Circle的原型链属性更改为Point的原型对象。
Circle.prototype = Object.create(Point.prototype);
//还可以为Circle的原型对象添加constructor和一些自定义的功能属性方法。
Circle.prototype.constructor = Circle;
Circle.prototype.area = function(){
    return Math.PI*this.radius*this.radius;
}
var c = new Circle(1, 2, 3);
c.move(2, 2);
//这里顺着Circle向上追溯,可以追溯到.move这个方法。
c.area();

函数的调用方式

  1. ( )的方式
    这种方式很常见,括号中传入参数。
  2. apply,call方法
    可以用apply,call来指定调用者以及参数。

函数参数的特点

  1. 形参个数不一定等于实参个数。
  2. Js函数参数传递都是值传递。
  3. Js函数在调用时系统并不做参数类型检查,但是程序员可以通过参数类型检查来实现函数的重载。

当函数实参个数小于函数形参个数时,未被赋值的函数形参的值是Undefined;当实参个数大于函数形参个数时,该如何获取这些实参呢?这里就要用到arguments对象

arguments

arguments对象是在函数执行时在函数内部生成的,表示接收的实参列表。

  • arguments对象常用属性
  1. length:实参个数
  2. 0…arguments.length-1: 实参属性名称(也就是对象中key-value结构中的key)
  3. callee: 函数本身
  • 范例
  1. 比较两个数字大小并返回大数
function max(a,b){
return a>b?a:b;
}

这个方法比较容易。

  1. 比较不定数量的数字大小并返回大数
function max(a, b){
    if ( max.length === arguments.length){
    return a>b?a:b;
    } 
    else {
        var _max = arguments[0];
        for(var i = 0; i < arguments.length; i++){
            _max > arguments[i]? _max : _max = arguments[i];
        }
    return _max;
    }
}

以上代码也可以简化成以下形式:

function max(){
    var _max = arguments[0];
    for(var i = 0; i < arguments.length; i++){
        if(_max < arguments[i]){
            _max = arguments[i];
        }
    }
    return _max;
}

值传递

在提到值传递之前,需要回顾一下原始类型和引用类型的区别。
在Js中,使用原始类型将一个值赋值给另一个数据,赋值结束后栈内存中确实存在两个数据。

var num1 = 123;
var num2 = num1;//栈内存中num1为123,num2为123

使用引用类型创建一个对象,这时栈内存中只保存了一个地址,这个地址指向堆内存中实际保存的对象。再将这个对象赋值给其他对象,实际上只是在栈内存中复制了一个地址,新建的那个对象同样指向堆内存中之前的对象。

var obj1 = {a:1};
var obj2 = obj1;

这类似于C++中的对象的浅拷贝。这可能会造成一些不可预见的问题,比如:

function setname(obj){
    obj.name = "obama";
    obj = {name:"clinton"};
}
var president = {name: "bush"};
setname(president);

这里函数中第二行把一个临时定义的对象地址赋给了实参中的obj,但是并没有影响到president的地址。

函数重载

我们可以通过Js的类型识别来实现函数功能的重载。

var define = function (name, deps, callback){
    var node, context;
    if(typeof name !== "string"){
        callback = deps;
        deps = name;
        name = null;
    }
    if(!Array.isArray(deps)){
        callback = deps;
        deps = null;
    }
    …………
};

这里类型检查的方法可以用JavaScript的数据类型中提到的方法实现。

RegExp (正则表达式构造器)

  • 构造器对象说明
    用于定义正则表达式对象,一个RegExp对象包含一个正则表达式和关联的标致。
  • 定义方法
  1. 第一种:直接定义的方法,通过斜杠来表示:/pattern/flags
  2. 第二种方法是使用new关键字加正则表达式构造器new RegExp(pattern[,flags]);
  • 构造器对象属性、方法
    只有一个prototype,没有别的。
  • 原型对象属性、方法
constructor
test
exec

RegExp.prototype.test

  • 功能
    使用正则表达式对字符串进行测试,并返回测试结果。
  • 语法
regexObj.test(str)
  • 范例
var reg = /^abc/i;
reg.test("Abc123"); //true
reg.test("1Abc23"); //false

Date

  • 构造器对象说明
    Date构造器一般用于定义日期对象
  • 定义方法
var myDate = new Date();
var myDate = new Date(2014, 3, 1, 7, 1, 1, 100);
  • 构造器对象属性、方法
    prototypeparsenow
  • 原型对象属性、方法
constructor
Date
getDate
getHours
setDate
setHours

由于都比较简单就不一一介绍了。

Math

  • 对象说明
    Math对象是拥有一些属性和方法的电议对象,主要用于数字计算
  • 对象属性
    几个常见的属性:E,PI,SQRT2
  • 对象方法
floor
random
abs
max
cos
ceil

这些方法主要用于数字计算。

Math.floor

  • 功能
    向下取整
  • 语法
    Math.floor(num)
  • 范例
Math.floor(0.97); //0
Math.floor(5.1); //5
Math.floor(-5.1); //-6
  • 相似方法
    ceil实现向上取整。
    round实现数字四舍五入为整数。

Math.random

  • 功能
    取随机数,返回0~1之间的浮点数。
  • 语法
    不含参数,直接使用,Math.random()
  • 范例
Math.random();

JSON

  • 对象说明
    用于存储和交换文本信息
  • 对象方法
    常用的有两个:parse,stringify

JSON.stringify

  • 功能
    将json对象序列化成字符串
  • 语法
JSON.stringify(value[,replacer[,space]])

这里的第一个参数value必须是一个JSON对象。

  • 范例
var json = {1:1, 2:'2', 3:{4:'4',5:{6:6}}};
JSON.stringify(json); //'{"1":1,"2":"2","3":{"4":"4","5":{"6":6}}}'

JSON.parse

  • 功能
    将json字符串转换成json对象。
  • 语法
JSON.parse(text[,reviver])
  • 范例
var str = '{"1":1,"2":"2","3":{"4":"4","5":{"6":6}}}';
JSON.parse(str);

//Object{1: 1, 2: "2", 3: Object}
    1: 1
    2: "2"
    3: Object
        4: "4"
        5: Object
            6: 6

全局对象

  • 属性
NaN
Infinity
undefined
  • 方法
parseInt
parseFloat
isNan
isFinite
eval
  • 处理URI方法
encodedURIComponent
decodeURIComponent
encodedURI
decodeURI
  • 构造器属性
    Boolean String Number Object Function Array Date Error
  • 对象属性
    Math JSON

NaN

  • 代表非数字值
    表示错误或无异议的运算结果4-"2a" 1*"7b" 2+"3"+ true - null
    NaN参与运算返回仍然是NaN NaN + 02 * NaN
    NaN不等于任何值,包括NaN本身4-"2a"==NaN //falseNaN==NaN //false
    可以用isNaN()判断运算结果是否为NaN。isNaN(NaN) //trueisNaN(4-"2a") //true

parseInt

  • 功能
    将字符串转化成10进制数字。
  • 语法
    它的语法比较简单:parseInt(string[,radix])
    第一个参数是字符串,第二个参数是一个进制(比如8进制,16进制),表示字符串的进制数,如果没有第二个参数传入,默认是10进制。
parseInt("10");       //10
parseInt("10",8);     //8
parseInt("10",16);    //16

parseInt("010");      //默认被当做10进制处理
parseInt("010",8);   //8

parseInt("0x1f");     //31
parseInt("0x1f",16);  //31
parseInt("1f");       //1 这里由于默认是十进制,f被忽略了
parseInt("1f",16);    //31

##eval
- 功能
eval()函数可计算某个字符串,并执行其中的JavaScript代码。
- 语法
比较简单:`eval(string)`
- 使用举例

var res = '{"error":"0","msg":"OK"}';
var obj;
if(!JSON){
obj = eval("("+ res+")");
}else{
obj = JSON.parse(res);
}

以上代码是将一个JSON字符串转换为一个JSON对象。在新版本浏览器中都有JSON对象,因此可以调用JSON.parse方法将JSON字符串转换为JSON对象。在老版本的IE浏览器中并没有JSON对象,所以可以通过eval这样的方法转换为JSON对象。但是在实际使用中,eval函数会带来一系列的安全性、性能、代码逻辑上的问题,因此通常不建议使用eval函数。

##encodedURIComponent
- 功能
用于将URI参数中的中文、特殊字符等作为URI一部分进行编码。
- 语法
`endodeURIComponent(URIstring)`
- 使用举例
通常我们在登录页面的时候要输入用户名密码这样一系列的参数,在点击提交时要进行编码,主要是为了防止注入性的攻击。
`var url="http://www.163.com/reg.html?name="+encodeURIComponent(name);`
第二种情况,在依赖URI进行参数传递时,需要考虑编码是否全都合法,比如:
`val url="test.html?param0="+"jack&lucy"+"&paraml="+"/image/test.png"`
由于具有"&"、"/"这种html中必须用转义字符的编码,会使Js解析错误,所以上面那种写法是错误的,应该使用:
`var url="test.html?param0="+encodeURIComponent("jack&lucy"+"&paraml")+encodeURIComponent("/image/test.png");`
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349